将C char [] []数组元素编组为C#

时间:2013-09-09 19:50:48

标签: c# c++ c interop marshalling

我看了看,尝试了我能想到或已经找到的所有建议。我仍然没有运气获得我需要的数据。

我正在使用第三方DLL,我认为这是用C语言编写的。我需要在C#中访问此DLL中的函数。在大多数情况下,我有这个工作,除了一个功能。我遇到问题的函数有以下标题:

uint queryNumOfServers(USHORT *NumOfServers, char ServerNames[8][16]);

我在C#应用程序中声明了以下内容

[DllImport("client.dll", CharSet=CharSet.Ansi]
public static extern uint queryNumOfServers(ref short numberofServer, StringBuilder serverNames);

我这称之为:

StringBuilder serverNames = new StringBuilder(128);
short numServers = -1;
queryNumberOfServers(ref numServers, serverNames);

问题是,虽然numberOfServers返回等于4,但我只在serverNames中获得一个名称。我在一个小C程序中测试了上面的C函数。我得到了numberOfServer = 4,但我还得到了4个名字。


我尝试过以下操作但没有成功:

[DllImport("client.dll", CharSet=charSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern uint queryNumOfServers(ref short numberOfServer,[MarshalAs(UnmanagedType.LPStr)] string serverNames);

调用
string serverNames = new string('\0', 128);
queryNumOfServers(ref numServers, serverNames);

使用此选项对serverNames没有任何更改。


开发环境是Visual Studio 2008.

2 个答案:

答案 0 :(得分:3)

经过大量的搜索和拔毛,这是对我有用的解决方案。

在我的C#应用​​程序中声明函数头:

[DllImport("client.dll", CharSet = CharSet.Ansi)]
public static extern uint queryNumOfServers(ref short numberOfServers, [MarshalAs(UnmanagedType.LPArray)] byte[,] serverNames);

然后调用如下:

byte[,] serverNames = new byte[8,16];
short numServers = -1;
queryNumberOfServers(ref numServers, serverNames);

这将返回一个双索引字节数组。从这里我使用Buffer.BlockCopy()和Encoding.UTF8.GetString()将我的字节数组转换为字符串数组。

答案 1 :(得分:0)

我会使用[StructLayout(LayoutKind.Sequential...][MarshalAs(UnmanagedType.ByValTStr...]

以下是两个很好的例子:

Marshalling a C 2-Dimensional fixed length char array

Marshaling a C++ two-dimensional fixed length char array as a structure member