Wednesday, July 04, 2007

Calling VC++ function pointer from C#

VS.NET 2005 :
------------------------------------

C# application :
--------------------------

1.Copy the VC++ DLL in to the debug folder of the newly created C# application

[DllImport("TestLib.dll",CallingConvention=CallingConvention.Cdecl)]
public static extern void SetCallback( MulticastDelegate callback );
[DllImport("TestLib.dll",CallingConvention=CallingConvention.Cdecl)]
public static extern void InvokeCallback(int count);

//Declaration For accessing the VC++ DLL function in C#


public delegate void CallbackDelegate( int count );

public static void Callback(int a)
{
Console.WriteLine("Callback: {0}", a);
}


public static void Main()
{
CallbackDelegate del = new CallbackDelegate( Callback );
Console.WriteLine( "Testing generated delegate..." );
SetCallback(del);

for(int i =0; i <5; i++)
{
InvokeCallback(i);
}
}


But I got an error while using this code ...
Function is executed but I got the error "'System.Reflection.Emit.TypeBuilder.Exit' not found".

Solution :
To avoid this error, we used the attribute with the delegate .

[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate void CallbackDelegate( int count );

Now the Error will not occur..


Reason :

The JIT compiler tracks the lifetime of object references in local variables (on the stack). It doesn't know that your unmanaged code uses the delegate. You can override it by using GC.KeepAlive() after the P/Invoke call. That doesn't actually generate any code, it just convinces the JIT compiler that the delegate instance should be kept alive past the call. This feature must have launched a thousand bugs. ( Example 1 in the KeepAlive() MSDN library topic is a scary example.)

No comments: