C# 中的非托管 C 代码通过引用字符串数组编组!
我真的很难把这个整理下来。
我有如下所示的非托管代码:
WORD HLP_GetDeviceNames (LPSTR *DevNames, WORD Max_Len, WORD Max_Num)
仅供参考,我没有编写此非托管代码,但必须使用它。
返回: 指示错误的 WORD。
DevNames:指向 char 数组的指针。基本上是一个将被修改并返回给我的字符串数组!
Max_Len:每个字符串的长度(据说必须是 256)
Max_Num:数组的长度。我正在使用另一个正在运行的 Invoke 调用,它告诉我设备的数量,以便我确切地知道要发送多少个字符串。
我已经使用 P/Invoke interop SignatureToolkit 解决了很多问题,但也阅读了一些内容以进一步了解。我现在的位置在这里:
[DllImport("UsbMeasLib.dll")]
public static extern ushort HLP_GetDeviceNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] ref StringBuilder[] DevNames, ushort Max_Len, ushort Max_Num);
我这样调用我的代码:
StringBuilder[] DevNames = new StringBuilder[deviceCount];
for(int i = 0; i< deviceCount; i++)
{
DevNames[i] = new StringBuilder().Append(' ', 256);
}
HachUsbMeasLib.HLP_GetDeviceNames(ref DevNames, 256, Convert.ToUInt16(DevNames.Count()));
我正在使用字符串生成器数组,因为我需要非托管代码来修改字符串生成器,以便它可以返回新字符串,因为字符串是不可变的。
当我运行代码时,我的数组未修改!
我不太确定发生了什么,但我认为这与 CLR 告诉非托管代码不要修改我的数组有关,而是创建一个新的引用(指针)。即使是这样,我也不知道如何解决。
感谢任何人都可以提供的任何见解!
I am having a really hard time getting this marshalling down.
I have umanaged code that looks like this:
WORD HLP_GetDeviceNames (LPSTR *DevNames, WORD Max_Len, WORD Max_Num)
Just FYI I did not write this unmanaged code but must use it.
Returns: WORD indicating an error.
DevNames: Pointer to an array of char arrays. Basically an array of strings that will be modified and returned back to me!
Max_Len: Length of each string (I am told this must be 256)
Max_Num: Length of array. I am using another Invoke call that is working that tells me number of devices so i know exactly how many strings to send.
I have used P/Invoke interop signatureToolkit to figure alot of this out but also read a bunch to get even further. Where I am now is here:
[DllImport("UsbMeasLib.dll")]
public static extern ushort HLP_GetDeviceNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] ref StringBuilder[] DevNames, ushort Max_Len, ushort Max_Num);
I call my code like this:
StringBuilder[] DevNames = new StringBuilder[deviceCount];
for(int i = 0; i< deviceCount; i++)
{
DevNames[i] = new StringBuilder().Append(' ', 256);
}
HachUsbMeasLib.HLP_GetDeviceNames(ref DevNames, 256, Convert.ToUInt16(DevNames.Count()));
I am using string builder array because I need the unmanaged code to modify the string builder so that it can return the new string since string is unmutable.
When I run the code, My array is unmodified!
I'm not really sure what is going on but I think it has something to do with CLR telling unmanaged code to not modify my array in place but instead creates a new reference(pointer). Even if this is the case, I dont know how to fix it.
Thanks for any insight anybody can offer!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试在低水平上工作。将 DevNames 参数声明为 IntPtr[]。通过以下方式准备它:
将此数组传递给 HLP_GetDeviceNames。要处理输出数据,请将 Marshal.PtrToStringAnsi 应用于每个 DevNames 成员。最后不要忘记用 Marshal.FreeHGlobal 释放 DevNames[i] 。
Try to work on low level. Declare DevNames parameter as IntPtr[]. Prepare it by the following way:
Pass this array to HLP_GetDeviceNames. To handle output data, apply Marshal.PtrToStringAnsi to every DevNames member. Don't forget to release DevNames[i] with Marshal.FreeHGlobal in the end.
我想出了这个。感谢任何回复的人。
我发现它是如何工作的。我只是提供内存空间,但我必须让封送知道我希望进出该对象,以便它允许非托管代码修改分配的空间。
我是这样做的:
我使用字符串而不是字符串生成器,因为非托管代码将简单地替换字符串,这是可以的。我正在取回数组指针,而不是修改后的字符串。托管代码只是更改指针数组以指向新的字符串对象(我认为)。
我为未修改的代码分配内存,然后让非托管代码更改那里的字符串。
这可行,但我不知道是否有任何潜在的内存泄漏或其他潜在问题。
I figured this one out. Thanks to anybody who replied.
I found out how it works. I simply supply the memory space but I have to let the marshaling know that I expect in and out with this object so it allows the unmanaged code to modify the allocated space.
I did it like this:
I use string instead of string builder because the unmanaged code will simply replace the string which is ok. I am getting the array pointer back, not modified strings. the managed code is just changing an array of pointers to point to new string objects (I think).
I allocate memory for the unamanged code then let the unmanaged code chane the strings there.
This works but I dont know if I have any potential memory leaks or other potential problems.