Tat*_*Tot 5 c c# c++ interop marshalling
我看了看,尝试了一切我能想到或已经找到的建议.我仍然没有运气获得我需要的数据.
我正在使用第三方DLL,我认为它是用C语言编写的.我需要在C#中访问此DLL中的函数.在大多数情况下,我有这个工作,除了一个功能.我遇到问题的函数有以下标题:
uint queryNumOfServers(USHORT *NumOfServers, char ServerNames[8][16]);
Run Code Online (Sandbox Code Playgroud)
我在C#应用程序中声明了以下内容
[DllImport("client.dll", CharSet=CharSet.Ansi]
public static extern uint queryNumOfServers(ref short numberofServer, StringBuilder serverNames);
Run Code Online (Sandbox Code Playgroud)
我这称之为:
StringBuilder serverNames = new StringBuilder(128);
short numServers = -1;
queryNumberOfServers(ref numServers, serverNames);
Run Code Online (Sandbox Code Playgroud)
问题是,虽然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);
Run Code Online (Sandbox Code Playgroud)
称之为
string serverNames = new string('\0', 128);
queryNumOfServers(ref numServers, serverNames);
Run Code Online (Sandbox Code Playgroud)
使用此选项对serverNames没有任何更改.
开发环境是Visual Studio 2008.
经过大量搜索和拉扯,这就是对我有用的解决方案。
在我的 C# 应用程序中将函数头声明为:
[DllImport("client.dll", CharSet = CharSet.Ansi)]
public static extern uint queryNumOfServers(ref short numberOfServers, [MarshalAs(UnmanagedType.LPArray)] byte[,] serverNames);
Run Code Online (Sandbox Code Playgroud)
然后调用如下:
byte[,] serverNames = new byte[8,16];
short numServers = -1;
queryNumberOfServers(ref numServers, serverNames);
Run Code Online (Sandbox Code Playgroud)
这将返回一个双索引字节数组。从这里我使用 Buffer.BlockCopy() 和 Encoding.UTF8.GetString() 将字节数组转换为字符串数组。