4

我正在为非托管 C dll 编写 C# 绑定。

dll 提供了 5 个钩子来返回多个数据:

typedef void (*t_libpd_printhook)(const char *recv);

并导出如下字段:

 EXTERN t_libpd_printhook libpd_printhook;

现在我正在使用Interop Assistant生成绑定代码,这给了我一个委托定义:

public delegate void t_libpd_printhook([In] [MarshalAs(UnmanagedType.LPStr)] string recv);

那么我可以使用一些神奇的互操作函数调用来设置 DLL 中的 t_libpd_printhook 字段吗?

4

2 回答 2

4

您可以使用LoadLibraryandGetProcAddress获取指向导出libpd_printhook变量的指针。然后您可以使用Marshal.WriteIntPtrMarshal.GetFunctionPointerForDelegate分配给委托人。

[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);

您将需要添加我为了简洁示例而删除的错误检查。

现在,如果您可以控制非托管库,我仍然建议添加一个函数来封装对该函数指针的写入。这对我来说感觉像是一个更好的界面。

于 2012-04-08T21:44:24.653 回答
3

PInvoke 不支持导出的变量。您需要创建一个非托管函数来获取您的委托并将其复制到该字段中。

于 2012-04-08T21:14:57.687 回答