我要将用C ++ / VisualStudio写的现有库/ DLL移植到代码块/ GCC。 Windows中的DLL已在C#,C,C ++,Python,Delphi,Java,VB.NET,LabVIEW等中进行了测试,并且运行良好且稳定。 但是,将其移植到Linux时,在从Mono / C#对其进行测试时遇到了问题,而在FreePascal和Python上却无法正常工作。
问题的根源是一个函数,该函数检测参数的设备,并通过参数返回一个整数,该整数包含检测到的设备的数目以及设备所在的路径列表(字符的ASCII字符串的数组): / p>
int DetectDevices(char ** DevicePaths);
我将结果复制到库中的方式是:
i=0;
for (vector<string>::iterator it=lstDetected.begin(); it!=lstDetected.end(); ++it)
strcpy(DevicePaths[i++], (*it).c_str());
在C#中,我使用以下代码声明外部函数:
[DllImport(LIBRARY_PATH)]
public static extern int DetectDevices([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] DevicePaths);
我想指出的是,实际上我在调用函数并获取返回值之前在C#中保留了一些内存空间:
string[] DevicePaths = new string[50];
for (int i=0; i<DevicePaths.Length; i++)
DevicePaths[i] = new string('\0', 255);
这在Windows / VisualStudio中工作正常,但在Linux / Mono中工作不正常。
用LPWStr替换LPStr并执行调试,表明字符已经到达,但对于LPStr中的所有字符,接收到的等效ASCII码为0,而在LPWStr中为63。
我认为这可能与字符编码有关,但是我可能错了。
有人对这里可能出什么问题有任何想法吗? 帮助将不胜感激!
答案 0 :(得分:1)
我终于设法找到了封送处理问题的解决方案。
在Windows(.NET Framework)和Visual Studio中,允许通过以下方式返回字符串的C数组(char数组):
[DllImport(LIBRARY_PATH)]
public static extern int DetectDevices([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] DevicePaths);
由于某种原因,这在Linux / Mono中不起作用,我不得不使用以下方法:
public static extern int DetectDevices(IntPtr[] pDevicePaths);
,然后在代码中使用以下方法检索每个字符串:
const int VCOUNT = 50;
const int MAXSTRINGSIZE = 255;
string[] MyValues = new string[VCOUNT];
IntPtr[] ptr = new IntPtr[VCOUNT];
for (int i = 0; i < ptr.Length; i++) ptr[i] = Marshal.AllocCoTaskMem(MAXSTRINGSIZE);
int n = DetectDevices(ptr);
if (n > 0) {
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder(Marshal.PtrToStringAnsi(ptr[i]));
MyValues[i] = sb.ToString();
}
}
这是一种更具C / C ++风格的样式,它增加了复杂性但很有意义。 因此,我相信Mono尚未完全实现,或者某个地方存在错误。
如果有人有更好的解决方案,我将不胜感激。
答案 1 :(得分:0)
尝试使用<span class="checkmark"></span>
,它将字符串转换为平台的默认字符串编码。对于Mono,这是LPTStr
。
UTF-8
=> ansi UnmanagedType.LPStr
=> Unicode UnmanagedType.LPWStr
=>平台默认值还有其他UnmanagedType.LPTStr
可能也可以帮助您……UnmanagedType
...?
如果这样做没有帮助,请考虑使用“自定义封送处理”或“手动封送处理”。