c# - 使用 IntPtr 将结构数组从 C# 传递到 C++

标签 c# c++ pinvoke

我有一个结构 -->

   public struct readers
   {
       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
       public IntPtr[] tag_list;
   };

编码必须在“IntPtr[] tag_list”和结构 TAG_IN_PARAM 之间完成

   [StructLayout(LayoutKind.Sequential)]
   internal struct TAG_IN_PARAM
   {
       public int vis_cnt;
       public bool valid;
   }

它也是一个数组 => TAG_IN_PARAM[] tag_list = new TAG_IN_PARAM[1000];

我想将结构“读者”从 C# 传递到 C++ DLL。但是,我一直在进行编码,但 DLL 端出现了垃圾值。

//分配内存 Marshal.StructureToPtr(tag_list[j], Reader.tag_list[j], false);

或者如果我有任何其他方式可以做到,请传达。 任何帮助,将不胜感激。 提前致谢。

最佳答案

根据您的评论,您尝试匹配的 C++ 类型是:

class Readers 
{
public:
    TAG_IN_PARAM* tag_list;
};

这是一个指向数组的指针。

但是您的 C# 代码声明了一个内联数组。您的 C# 代码将与此匹配:

class Readers 
{
public:
    TAG_IN_PARAM tag_list[1000];
};

显然,这不是您想要的方式。

您需要更改 C# 代码以使其匹配。不幸的是,当数组位于结构内部时,编码器似乎不会将数组编码为指向第一个元素的指针。由于数组是结构中唯一的东西,您应该简单地将数组作为参数传递。

或者,如果您绝对需要在结构中传递数组,那么我认为您需要手动编码。像这样。

public struct readers
{
    public IntPtr tag_list;
};

然后您可以简单地固定您的阵列。

TAG_IN_PARAM[] tag_list = ...;
GCHandle pinnedArray = GCHandle.Alloc(tag_list, GCHandleType.Pinned);
readers r;
r.tag_list = pinnedArray.AddrOfPinnedObject();
// call function passing r
pinnedArray.Free();

不幸的是,这并不完全有效,因为 C# bool 不可 blittable。因此,您可以通过为该字段使用不同的类型来解决该问题。例如 byteint 取决于 C++ 端的内容。

另一个选项是在每个字段上使用 Marshal.StructureToPtr。那会像这样运行:

TAG_IN_PARAM[] tag_list = ...;
int structSize = Marshal.SizeOf(typeof(TAG_IN_PARAM));
r.tag_list = Marshal.AllocHGlobal(tag_list.Length*structSize);
IntPtr ptr = r.tag_list;
for (int i = 0; i < tag_list.Length; i++)
{
    Marshal.StructureToPtr(tag_list[i], ptr, false);
    ptr += structSize;
    // or on older versions of .net without arithmetic support on IntPtr
    // ptr = (IntPtr) (long)ptr + structSize;
}
// call function passing r
Marshal.FreeHGlobal(r.tag_list);

关于c# - 使用 IntPtr 将结构数组从 C# 传递到 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18781402/

相关文章:

c# - 如何在 GetInstance 调用/替代解决方案后在简单注入(inject)器中进行注册?

c# - Azure 移动服务和 Asp.net 身份架构

c# - 转换并合并两个相同接口(interface)但不同类型的列表

c++ - 集: C++ vs C#的快速交集

c++ - 如何使用 XCB 在根窗口上绘制?

c# - 在 C# 中建模 C/C++ union

c# - C# 中的线程安全属性

c++ - C++ 字符串中的 cin>>str+1 是什么?

.net - 为什么对 AddDllDirectory 的调用失败并显示 "Parameter is incorrect"?

c# - C#通过P/Invoke一次播放多种声音