Thanks Willy,
The link was a lot of help. I have still one problem though that I hope
someone can help with. When I take the example and modify the callback
function to have a parameter, I get unexplained behaviour where my managed
callback function is invoked 2x's. I think this has to do with the calling
convention (if I add __stdcall to the ANSWERCB typedef line, the problem
goes awa), but I'm not sure what I should really do (is there a better
answer, something that makes more sense?) to fix the problem.
Can someone help - I have included modified test below. When I run it, the
GetNumber method is invoked 2x's - once when expected, and once after
execution returns to the main() immediately after having executed the first
TakesCallback() method.
Thanks, Tyler
---------------------------------
// MarshalDelegate 2.cpp
// compile with: /clr
#include "stdafx.h"
#include <iostream>
using namespace System;
using namespace System::Runtime ::InteropServic es;
#pragma unmanaged
typedef int (/* __stdcall */ *ANSWERCB)(void *);
static ANSWERCB cb;
int TakesCallback(A NSWERCB fp, void * fpValue) {
cb = fp;
if (cb) {
printf_s("[unmanaged] got callback address (%d), calling it...\n",
cb);
return cb(fpValue);
}
printf_s("[unmanaged] unregistering callback");
return 0;
}
#pragma managed
public delegate int GetTheAnswerDel egate(void *);
int GetNumber(void * fpValue) {
Console::WriteL ine("[managed] callback!");
static int x = 0;
return ++x;
}
static GCHandle gch;
int main() {
GetTheAnswerDel egate^ fp = gcnew GetTheAnswerDel egate(GetNumber );
gch = GCHandle::Alloc (fp);
IntPtr ip = Marshal::GetFun ctionPointerFor Delegate(fp);
ANSWERCB cb = static_cast<ANS WERCB>(ip.ToPoi nter());
Console::WriteL ine("[managed] sending delegate as callback...");
int answer = TakesCallback(c b, 0);
// possibly much later (in another function)...
Console::WriteL ine("[managed] releasing callback mechanisms...") ;
TakesCallback(0 , 0);
gch.Free();
}
---------------------------------
"Willy Denoyette [MVP]" <wi************ *@telenet.be> wrote in message
news:99******** *************** ***********@mic rosoft.com...
http://msdn2.microsoft.com/en-us/lib.../367eeye0.aspx
Willy.
"Tyler" <Ty****@newsgro ups.nospam> wrote in message
news:ek******** *****@TK2MSFTNG P14.phx.gbl... Can someone help by explaining why the following class will not compile
(VS2005), and what can be done to pass the function pointer to the "C"
method?
When I compile the following program, I get "error C2664: 'CMethod' :
cannot convert parameter 1 from 'Test::DoItFn ^' to 'void (__cdecl
*)(void *)':
#include "stdafx.h"
void CMethod(void (* pfvFunPointer)( void *), void * pfvValue)
{
(*pfvFunPointer )(pfvValue);
return;
}
ref class Test
{
public:
delegate void DoItFn(void * pfvValue);
virtual void DoIt(void * pfvValue)
{
return;
}
virtual void Run()
{
DoItFn ^ tvfnDoIt = gcnew DoItFn(this, &Test::DoIt) ;
CMethod(tvfnDoI t, nullptr);
return;
}
};
Can someone please help? Any good documentation references would also be
appreciated.
Thanks, Tyler