Habte fen
Habte fen

Reputation: 11

managed system.timer over un managed code

New to the groups, sorry if this the wrong forum/etiquette. I am coding a c++ application that requires the use of a timer-triggered event handler. I decided to use the timer provided in System::Timers::Timer. My understanding of the next part is not very good, as my code may reveal, but as I understand it, my application is "unmanaged C++", whereas the timer extension from the system DLL is managed. Therefore I needed to use the gcroot template to allow the inclusion of the "managed" timer code.

#include <vcclr.h>

#using <mscorlib.dll>
using namespace System;

#using <System.dll>
using namespace System::Timers;

class DataStream
{
   public:
   DataStream():m_N(48),m_saving(false)
   {
      // set up the window timer
      m_Timer = gcnew Timer;
      m_Timer->Elapsed += gcnew
      ElapsedEventHandler(DataStream::nextCandle);
      m_Timer->Interval= CANDLE_DURATION * 1000;
      m_Timer->AutoReset= true;
      m_Timer->Enabled=true;
    }; // default constructor

private:
   gcroot<Timer^> m_Timer; /* use gcroot because can't use managed object in unmanaged class. */

   void nextCandle(Object ^sender, ElapsedEventArgs ^e);

};

void DataStream::nextCandle(Object ^sender/*source*/, ElapsedEventArgs ^e/*e*/)
{
   // do some stuff ...
}

Here's the problem, upon compilation, I get this error:

Compiling...
dataStream.cpp
c:\blah\dataStream.h(18) : error C3867: 'DataStream::nextCandle':
function call missing argument list; use '&DataStream::nextCandle' to
create a pointer to member
c:\blah\dataStream.h(18) : error C3350:
'System::Timers::ElapsedEventHandler' : a delegate constructor expects
2 argument(s)

At first, I didn't include the & reference suggested by the compiler because most examples I had seen do not use this.

Upon inclusion, changing:

m_Timer->Elapsed += gcnew ElapsedEventHandler(DataStream::nextCandle);

to....

m_Timer->Elapsed += gcnew ElapsedEventHandler(&DataStream::nextCandle);

I get the following error on compilation:

c:\blah\dataStream.h(18) : error C3364:
'System::Timers::ElapsedEventHandler' : invalid argument for delegate
constructor; delegate target needs to be a pointer to a member function

So I'm stuck at this point. I'm not sure if the solution is a few small changes away from where I am, or if these errors are indicative of a larger problem (i.e. me using the gcroot template and mixing managed and unmanaged code with zero experience in that). I'm using Visual C++ Express Edition Beta.

Upvotes: 1

Views: 3032

Answers (2)

Padmoz
Padmoz

Reputation: 41

For VS2010 CLI/C++

The code presented is unmanaged C++. If the Datastream class was managed it would be

class ref DataStream {...}

instead of the presented

class DataStream {...}

Also if the class was managed then

gcroot<Timer^> m_Timer;

would be

Timer^ m_Timer;

The nextCandle method needs to be static, or from a managed class.

A static nextCandle declaration would look like:

class DataStream {

private:
    gcroot<Timer^> m_Timer; /* use gcroot because can't use managed object in unmanaged class. */

    static void nextCandle(Object ^sender, ElapsedEventArgs ^e);

}

To add an EventHandler that uses a static nextCandle

m_Timer->Elapsed += gcnew ElapsedEventHandler(DataStream::nextCandle);

To add an EventHandler that uses a nextCandle method from a managed class

m_Timer->Elapsed += gcnew ElapsedEventHandler(this, &DataStream::nextCandle);

Good example from MSDN under examples at the very bottom.

Upvotes: 4

DanDan
DanDan

Reputation: 10562

Your nextCandle function needs to be static, or a stand alone function. It's not an error due to mixing managed and unmanaged code, this is all managed code.

The problem is your member function passes a hidden this parameter, which is rarely the function prototype expected.

Upvotes: 0

Related Questions