2011-01-05 43 views
0

我想从c dll导入一个函数到C#中。 C函数看起来像这样正确的C#dll导入功能

unsigned short write_buffer(unsigned short device_number, unsigned short word_count, unsigned long buffer_link, unsigned short* buffer) 

我在C#进口尝试看起来像这样

[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 

我有点困惑如何使一个适当的调用传递消息作为缓冲区。 deviceNumber为2,是的wordCount 32和buffLink为0,所以我知道调用应该是这个样子

write_buffer(2,32,0, msgs[key]); 

显然,我得到了IntPtr的无效参数。打这个电话的正确方法是什么?

回答

2

什么缓冲区应该包含和其数据流向哪个方向是相当不清楚的。你的字典表明它应该是一个数组。只需声明如下:

private static extern ushort write_buffer(.., ushort[] buffer); 

并在调用中使用msgs [key] .ToArray()。

在write_buffer()调用中使用常量并不是一个可能的场景,但应该有msgs [key] .Count在那里。

+0

谢谢,对不起,问题有点不清楚,但你提供的答案似乎工作正常。 – poco 2011-01-05 18:55:11

1

您可以使用标记为here的P/Invoke Interop Assistant工具生成P/Invoke签名。

在MSDN 杂志,张翼和小英郭 的2008年1月发行对管理之间 非托管代码编组发表了CLR内而外列 。在该列中,他们引入了P/Invoke Interop Assistant,一个自动GUI和 命令行实用程序,用于在托管和非托管 签名(双向)之间转换 。这个 转换当然不仅仅限于Windows签名的 ;给 工具一个你自己的C头文件 的片段,它会尽职尽责地把它们转换成漂亮的C# [DllImport]的。

+0

它在这里没有帮助。如果C声明有SAL注释,该工具只能做一个体面的工作。在这里没有,没办法告诉这是否是一个数组。 – 2011-01-05 17:57:39

0

如果你不介意将代码标记不安全的,你可以简单地做:

fixed(ushort* pData = msgs[key]) 
{ 
    write_buffer(2,32,0, pData); 
} 

,并宣布你的DllImport采取USHORT *作为最后一个参数。

另一种方法是使用Marshal.StructureToPtr将数组编码到固定存储器中。这要求您首先使用AllocHGlobal分配内存,然后使用FreeHGlobal释放内存。