如何将 uint[] c# 传递给 c++ dll?
Posted
技术标签:
【中文标题】如何将 uint[] c# 传递给 c++ dll?【英文标题】:how to pass uint[] c# to c++ dll? 【发布时间】:2021-03-29 11:30:02 【问题描述】:我正在开发一个与 C++ DLL 通信的 C# 程序。
提供的C++ DLL中的结构类型如下:
struct ST_TEST
unsigned long* anIDs;
unsigned long anIDCount;
;
我为匹配上述结构而创建的C#结构如下:
[StructLayout(LayoutKind.Sequential)]
public struct ST_TEST
public IntPtr anIDs;
public uint anIDCount;
在那之后,我想做的是设置 C# 结构的对象以将该结构从 C# 传递给 C++,如下所示:
uint[] IDs = 12824874, 7865845, 45875792 ;
ST_TEST stTest = new ST_TEST();
stTest.anIDCount = (uint)IDs.Length;
IntPtr buffer = Marshal.AllocHGlobal(IDs.Length);
try
Marshal.Copy(IDs, 0, buffer, IDs.Length);
stTest.anIDs = buffer;
//... call c++ dll
finally
Marshal.FreeHGlobal(buffer);
如上执行时,Marshal.Copy()
出现如下错误:
无法从 uint[] 转换为 int[]
如何将uint[]
作为unsigned long*
传递给C++ DLL?
【问题讨论】:
郑重声明,您的工作水平太低且没有适当的工具,Span<>
和 stackalloc
。您应该选择一个适当的低级代码,或者只使用托管数组(就像您已经分配的,您的 IDs
)并正确注释您的结构以按原样与编组器一起工作。
请解释得通俗一点。你的意思是中间创建一个clr项目比较好?
【参考方案1】:
您不能使用uint
,因为 Marshal 类没有该类型的重载,因为它是
不符合 CLS。
但是,由于您要复制数组中的字节,int
将起作用,因为它的大小正确,
并且 C++ 代码在接收到数组元素时仍将其视为uint
。
另外,请注意,使用Marshal.AllocHGlobal()
时,您必须指定字节数,而不是
数组元素的数量。
一定不要调用Marshal.FreeHGlobal()
,直到 C++ 函数返回 AND 不再是
使用数组指针。
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct ST_TEST
public IntPtr anIDs;
public int anIDCount;
public class Program
public static void Main()
try
Console.WriteLine("Hello World");
int[] IDs = 12824874, 7865845, 45875792 ;
ST_TEST stTest = new ST_TEST();
stTest.anIDCount = IDs.Length;
IntPtr buffer = Marshal.AllocHGlobal(IDs.Length * sizeof(int));
Marshal.Copy(IDs, 0, buffer, IDs.Length);
stTest.anIDs = buffer;
// ... call native function
// ...
finally
Marshal.FreeHGlobal(buffer);
【讨论】:
Marshal.FreeHGlobal
应该在 finally
块中
最后,uint是不行的,我必须把它改成int.. uint.maxvalue之类的就不行了.. 提供的c++ dll很难用.谢谢你的好榜样。还检查了 finally 语句中的 put free 部分。非常感谢大家。以上是关于如何将 uint[] c# 传递给 c++ dll?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确地将这些转换为 c#,marshall,以便我可以将这些结构传递给 DLL (c++)?
将 char*[] 从 c++ dll Struct 传递给 c#