如何将 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?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 COM 对象的 C# 引用传递给 C++ DLL

如何正确地将这些转换为 c#,marshall,以便我可以将这些结构传递给 DLL (c++)?

将 char*[] 从 c++ dll Struct 传递给 c#

将 C# 字符串传递给 C++ dll 在发布版本中失败

使用 DLL 将 C# StringBuilder / 字符串传递给 C++ char*

将 c++ dll 的 char 指针数组传递给 c# 字符串