Difficult to say from what you have shown. You can pin a handle to a managed object only temporarily, since a pin_ptr can only be created on the stack. Therefore, if you have something like this:
IntPtr YourClass::GetFuncPointer()
{
FuncDelegate^ fp = gcnew MessageFuncDelegate(this, &Handler);
pin_ptr pinnedFunctionPointer = &fp;
return ((ProcMessageFunc)pinnedFunctionPointer);
}
then you effectively have only pinned fp for the duration of this method call. A correct way to do this depends on your scenario. I'd recommend something along the lines of the following (I didn't compile it, but you get the idea):
public ref class ClientRegistrar abstract sealed {
static FuncDelegate^ s_ManagedReceiverList;
// ...
public static void RegisterClient(YourClient^ p\_Client)
{
// thread safety for free
s\_ManagedReceiverList +=
gcnew MessageFuncDelegate(p\_Client, &YourClient::Handler);
// here I assume that ::Receiver is an unmanaged global function which
// takes a funtion pointer of type ProcMessageFunc. Don't know
// if you need to deal with multiple registrations....
::Receiever((ProcMessageFunc)Marshal::GetFunctionPointerForDelegate(s\_ManagedReceiver));
}
public static void UnregisterClient(YourClient^ p\_Client)
{
s\_ManagedReceiverList -=
gcnew MessageFuncDelegate(p\_Client, &YourClient::Handler);
// use the same schema to unregister from the native receiver
}
}
Usage (C#):
YourClient tClient = new YourClient();
// ...
ClientRegistrar.RegisterClient(tClient);
// ...
s_ManagedReceiverList and any YourClient instance you register via RegisterClient will be kept alive as long as the current application domain will exist. Implement UnregisterClient if you need more fine grained control. A delegate does not need to be pinned, the CLR takes care of proper handling of that. It just needs to be kept alive. Cheers, Paul