Callback to C# from unmanaged legacy DLL

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: PaulR (paul_roberts_at_hotmail.com)
Date: 05/12/04


Date: 12 May 2004 05:28:28 -0700

I am running out of ideas (and hair) so any help would be greatly
apreciated. I am attempting to work with unmanaged code which must
make asynchronous callbacks to C#.

I have inherited a legacy DLL, supposedly written in C, which I cannot
modify. The DLL implements the API of a proprietary application which
I have to use.

The header file for the DLL declares a function for registering a
callback:

int regConnectCB( void (*pUsrFunc)(char* pchMsg, int iErrCode)) ;

I have used the following in C# as an attempt to communicate with
this:

// Declare the delegate
public delegate void pConnectCB(string pchMsg, int iErrCode) ;

public class App
{

  // Enable access to unmanaged code. Use 8 bit characters.
  [DllImport("DLL.dll", CharSet=CharSet.Ansi,
CallingConvention=CallingConvention.Cdecl)]
  public static extern int regConnectCB(pConnectCB pUsrFunc) ;

  // Create the function to be used for callbacks
  public static void ConnectCB(string pchMsg, int iErrCode)
  {
    // Don't care about what the method is doing at the moment
    Console.WriteLine("ConnectCB() called") ;
  }

  public static void Main()
  {
    // instantiate the delegate
    pConnectCB con = new pConnectCB(ConnectCB) ;

    // Call the DLL function to register the delegate
    regConnectCB( con ) ;

    // Loop forever awaiting callback
    while(true) sleep(1000) ;
 
    // unreachable line of code for keeping delegate instance alive
whilst
    // waiting for asynchronous callback from Legacy DLL
    GC.KeepAlive(con) ;
  }
}

The DLL is meant to spawn a child thread and asynchronously callback
to the C# delegate. However, I get nothing - no errors, crashes,
nada.

Most of the APIs few function calls work without a problem when I'm
calling unmanaged code directly from C#. My problem is with purely
with the callbacks.

I also know that the DLL is working because we have a C++ demo app
which is using the DLL - it definitely gets callbacks from the DLL to
its methdos. As far as possible I've copied the structure and logic
of the C++ code. In addition, the DLL saves tracing info to a text
file which indicates that the callback has been registered.

Just in case it's a problem with the CDecl calling convention (ie. the
DLL wants to use Cdecl but the C# delegate won't) - I've tried hacking
the IL code from the class as per other postings but still nothing.

I've also tried other datatypes for the delegate declaration eg.
IntPtr instead of string to match char*. For that matter, I've even
tried it with unsafe char*. Again, no errors, and no callbacks.

I've tried alternative methods to GC.KeepAlive() for keeping the
delegate reference (and hence the delegate struct) alive.

As fas as I can see I, if the DLL has its own threads, there is no
need for me to do thread creation in my C# app. Am I correct in this
assumption?

My backup plan is to write a wrapper in C++ but I dearly want to avoid
doing this (because my C++ is non-existant).

I've tried everything I can think of. If you can offer any
suggestions I would be very grateful.

Many thanks

Paul.



Relevant Pages

  • Re: C#.net custom control
    ... The custom control will be in whatever executable corresponds to the ... How can delegate(s) be accessed by code when the reference to a delegate ... How to compilethe custom contol to generate a DLL? ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: C#.net custom control
    ... I have a delgate in one project and I want to have the delegate be executed from a click event in another project. ... As long as the types are visible in the same project (which that itself _is_ related to the project references), passing the delegate object is as simple as just passing the reference to a method, subscribing to an event, etc. ... How to compilethe custom contol to generate a DLL? ...
    (microsoft.public.dotnet.languages.csharp)
  • Unamanged types in managed interface generates TypeLoadExcep
    ... The failure happened when calling a delegate whose interface is ... abstract and whose implementation overrides the interface method. ... and opening the DLL containing the implementation and then the one ... for the type load failure was caused by the inability to ...
    (microsoft.public.dotnet.languages.vc)
  • Re: callbacks
    ... I am writing the UI part and my collegue is writing a dll which will ... When I create an object from the dll, I pass the function pointer (delegate) ... > void MyCppMethod ... > 3) a p/Invoke for the Cpp method: ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: using unmanaged C++ dll in C#
    ... If unmanaged code and CLI ... of unmanaged dll to managed C++/CLI dll. ... namespace CLRWrapper ... _CppLib = new CCppLib; ...
    (microsoft.public.dotnet.languages.csharp)