We help IT Professionals succeed at work.

Managed C++ How to pass a pointer to a class instance to a static callback?

So in my quest to integrate a native C++ dll callback into a managed C++ project, I have now succeeded (with much help!) to import the dll calls including the callback call into the project by the use of delegates. The callback is a static member function of a managed class, in fact the class of the only Form of that small .NET project.

Now my problem is that I don't know how to get access to the members of the managed class from the callback function. Indeed since it is a static function, I cannot use the handy "this->" function.

Back in the MFC days, I would have used the AfxGetApp() function to grant me access to the outside world, is there an equivalent in .NET?

Another option might be this: I can pass a "void* pContext" pointer to the dll function which registers the callback function. So I thought I should cast the "this" pointer to my Form class instance to a "void*" pointer and do the reverse from inside my callback.

The code looks like this :

////////////////code///////////////////////////////

typedef void (__clrcall *func_t2)(TestCamera2::Form1 ^const);//for casting from a Form^ type to a void* type

func_t fp2 = func_t(Marshal::GetFunctionPointerForDelegate(fp).ToInt32());//delegate to the callback function

m_lCallbackRegistration = CameraAddStreamingCallback(m_hCamera, fp2, func_t2(this));//this compiles fine

//////////////////////////////////////////////////////

Then in my callback I have to cast back my pContext pointer from void* to Form^.

I tried to do it the following way:

////////////////code///////////////////////////////

typedef TestCamera2::Form1 ^const (__clrcall *func_t3)(System::Void*);
func_t3(pContext)->Preview->Name = L"Preview";//doing something on a member of the Form class

//////////////////////////////////////////////////////

However I get the following compiler error which makes me think that my cast did not succeed:

error C2227: left of '->Preview' must point to class/struct/union/generic type

What am I doing wrong...?

Comment
Watch Question

Senior Software Engineer (Avast)
CERTIFIED EXPERT
Commented:
The typedef you've created is creating a function pointer and casting the void * to that function pointer, this is why it's not working. That trick will work when you can't to cast a static function pointer to void * and back but not for this. Have you tried something like the following?

typedef TestCamera2::Form1 ^const pForm pform_t;
pform_t pForm = form_t(pContext);

This is attempting to constructor cast a form pointer (similar to constructor casting a function pointer).

All this is doing is the same as this...

typedef int * pint_t;
int i = 0;
void * pvoid = &i;
int *pint = pint_t(pvoid);

It's constructing a new pointer object and using it to initialize your pointer type. It's not different from this...

int i = int(0);

NB. I am unable to test this myself -- sorry.

Author

Commented:
Thanks Evilrix,

However your code does not compile. here are the errors:

error C2146: syntax error : missing ';' before identifier 'pform_t'
error C2065: 'pform_t' : undeclared identifier      
error C2146: syntax error : missing ';' before identifier 'pForm'
error C3861: 'form_t': identifier not found

Cheers,

bob
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
Hmmm.

Ok Bob, I'll try and recreate here and get back to you.

-Rx.
Which version of Visual Studio are you using?
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
>> Which version of Visual Studio are you using?
His previous thread on a similar track suggests VS2005.
http://www.experts-exchange.com/Programming/Languages/CPP/Q_23111103.html

Author

Commented:
Yes, using VS2005.
Actually I went around the problem by making the callback non-static (originally I assumed it had to be static). So now I can call the class-members from my callback and it seems to work fine.