c# - 从 C# 设置非托管 C dll 的公共(public)字段

标签 c# dll delegates interop dllimport

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

dll 提供了 5 个钩子(Hook)来返回几个数据:

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

并导出一个字段,如:

 EXTERN t_libpd_printhook libpd_printhook;

现在我正在使用 Interop Assistant生成绑定(bind)代码,它只给了我一个委托(delegate)定义:

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

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

最佳答案

您可以使用 LoadLibraryGetProcAddress 获取指向导出的 libpd_printhook 变量的指针。然后,您可以使用 Marshal.WriteIntPtrMarshal.GetFunctionPointerForDelegate 分配给委托(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);

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

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

关于c# - 从 C# 设置非托管 C dll 的公共(public)字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10066550/

相关文章:

c# - 资源文件夹的相对路径自动更改为C#中的绝对路径时出错

c# - 我怎样才能使我的函数在 ArrayList 上以 "Contains"的速度运行?

c# - 无法将字符串值转换为日期时间,包括毫秒

delphi - 在主机应用程序和 DLL 之间传递包含方法的记录

ios - 使用 AFNetworking 2.0 创建自己的委托(delegate)和协议(protocol)

java - Java 与 .NET Func<> 和 Action<> 委托(delegate)最接近的是什么?

c# - NHibernate ISession.save(newTransientEntity) 是否只会返回生成的 Id,但不会更新实体的 Id 属性?

.net - 在哪里可以获得 Microft SharePoint 程序集?

c++ - Windows 上的 Qt QMYSQL "Driver not loaded"

c# - 为什么编码回调委托(delegate)结构会导致 AccessViolationException