c#编组尝试将结构从cpp dll返回到c#应用程序,该应用程序被分配为它自己的dll

Posted

技术标签:

【中文标题】c#编组尝试将结构从cpp dll返回到c#应用程序,该应用程序被分配为它自己的dll【英文标题】:c# marshalling try to return struct from cpp dll to c# application which gets allocated be the dll it self 【发布时间】:2020-10-01 11:35:48 【问题描述】:

我有以下问题:

我尝试从我的 c# 应用程序中调用这个 c++ 函数:

int get_struct_from_dll (some_struct** return_struct);

int get_struct_form_dll (some_struct** return_struct) 
     some_struct st;
     st.some_void_pointer = nullptr;
     st.some_string = "some_string";

     some_struct* st_ptr = &st;
     *return_stuct = return_struct;

return 1;

return_struct 是一个双指针,因为get_struct_from_dll 必须自己分配内存。 它也只包含一个元素,因此不需要大小信息。

some_struct 看起来像这样:

typedef struct 
     void        *some_void_pointer;      
     const char  *some_string;                                                                       
 some_struct;

现在在 c# 方面:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct some_struct

        public IntPtr instance;
        [MarshalAs(UnmanagedType.LPStr)]
        public string host;

        [DllImport(_dllPath)]
     
        public static extern ReturnTypes get_struct_form_dll (IntPtr server);

        IntPr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));

        get_struct_form_dll(ptr);

        IntPtr ptrptr = Marshal.ReadintPtr(ptr);

        some_struct st= (some_struct) Marshal.PtrToStructure(ptrptr, typeof(some_struct));
        

现在的问题是,当我打印 st 时,它只会返回垃圾,但不会抛出任何错误。

请帮忙!

我也尝试过: 我确实将我的 c# 代码更改为以下内容:

    [DllImport(_dllPath)]
     
        public static extern ReturnTypes get_struct_form_dll (out IntPtr server);

        IntPr ptr;

        get_struct_form_dll(out ptr);

        some_struct st = (some_struct) Marshal.PtrToStructure(ptr, typeof(some_struct)); 

这导致与之前完全相同的结果。

【问题讨论】:

out 可能会解决此问题,例如 public static extern ReturnTypes get_struct_form_dll (out IntPtr server); out 没有修复它。我得到完全相同的结果。 【参考方案1】:

我终于找到了解决问题的方法。

解决办法是c++端返回后自动释放内存。 这会导致 c# 读取未分配的内存,这显然不起作用。

因此解决方法是将c++端改成如下:


int get_struct_form_dll (some_struct** return_struct) 

  some_struct* st = (some_struct*) malloc(sizeof(some_struct));
  
  *return_struct = st;

  return 1;



这可以防止数据在调用后被删除。

要小心,因为此时 malloc 调用永远不会被释放。 这会导致内存泄漏。

【讨论】:

以上是关于c#编组尝试将结构从cpp dll返回到c#应用程序,该应用程序被分配为它自己的dll的主要内容,如果未能解决你的问题,请参考以下文章

将浮点数组编组到 C#

C#编组来自C++ DLL的无符号字符返回值[重复]

在 c# 中将 uchar[] 从本机 dll 编组为 byte[] 的正确方法

从 c# dll 调用/编组字符串到非托管代码

创建要在 C# 中编组的 C++ Dll 的最佳实践 [关闭]

将 C++ int* 编组为 C#