我正在尝试将函数从c dll导入C#。 c函数看起来像这样
unsigned short write_buffer( unsigned short device_number, unsigned short word_count, unsigned long buffer_link, unsigned short* buffer)
我对C#import的尝试看起来像这样
[DllImport("sslib32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern ushort write_buffer(ushort deviceNumber, ushort wordCount, UInt32 bufferLink, IntPtr buffer)
在C#中我有一个消息词典,我想传递给这个函数。字典看起来像这样:
Dictionary<string, List<ushort>> msgs
我有点困惑如何做一个正确的调用来传递msgs作为缓冲区。 deviceNumber为2,wordCount为32,buffLink为0.所以我知道调用看起来应该是这样的
write_buffer(2,32,0, msgs[key]);
显然我得到了IntPtr的无效参数。拨打此电话的正确方法是什么?
答案 0 :(得分:2)
目前还不清楚缓冲区应该包含什么以及它的数据流向哪个方向。你的字典表明它应该是一个数组。只要这样声明:
private static extern ushort write_buffer(.., ushort[] buffer);
并在通话中使用msgs [key] .ToArray()。
在write_buffer()调用中使用常量并不会使这种情况成为可能,但某处应该有msgs [key] .Count。
答案 1 :(得分:1)
您可以使用引用为here的P / Invoke Interop Assistant工具生成P / Invoke签名。
在2008年1月的MSDN中 杂志,张毅和郭小英 已发布CLR Inside Out专栏 管理和管理之间的编组 非托管代码。在那一栏中,他们 介绍P / Invoke Interop 助手,自动GUI和 用于转换的命令行实用程序 托管和非托管之间 签名(两个方向)。这个 转换当然不受限制 只是为了Windows签名;给 工具你自己的C头的片段 文件,它将尽职尽责地转换 他们用漂亮的印花C# [的DllImport]的
答案 2 :(得分:0)
如果您不介意将代码标记为不安全,您可以执行以下操作:
fixed(ushort* pData = msgs[key])
{
write_buffer(2,32,0, pData);
}
并声明你的DllImport将ushort *作为最后一个参数。
另一种方法是使用Marshal.StructureToPtr将阵列编组到固定内存中。这要求您先使用AllocHGlobal分配内存,然后使用FreeHGlobal释放内存。