Set public field of unmanaged C dll from C#

c#, delegates, dll, dllimport, interop

Solution

You can use `LoadLibrary` and `GetProcAddress` to obtain a pointer to the exported `libpd_printhook` variable. You can then use `Marshal.WriteIntPtr` and `Marshal.GetFunctionPointerForDelegate` to assign to the delegate.

[DllImport("kernel32", SetLastError=true, CharSet=CharSet.Unicode)]
static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, 
    SetLastError=true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);

.....

IntPtr lib = LoadLibrary(@"mydll.dll");
IntPtr plibpd_printhook = GetProcAddress(lib, "libpd_printhook");
Marshal.WriteIntPtr(plibpd_printhook, 
    Marshal.GetFunctionPointerForDelegate(mydelegate));
FreeLibrary(lib);

You will want to add the error checking that I excised in the interests of a concise example.

Now, if you are in control of the unmanaged library I would still recommend adding a function to encapsulate writing to this function pointer. That feels like a better interface to me.

Problem

I am writing a C# binding for an unmanaged C dll. The dll provides 5 hooks to return several data: ``` typedef void (*t_libpd_printhook)(const char *recv); ``` and exports a field like: ``` EXTERN t_libpd_printhook libpd_printhook; ``` now i was using Interop Assistant to generate the binding code, which gave me just a delegate definition: ``` public delegate void t_libpd_printhook([In] [MarshalAs(UnmanagedType.LPStr)] string recv); ``` So is there some magic Interop function call i can use, to set the t_libpd_printhook field in the DLL?

Original source

Related problems