p/invoke 方法返回空结构

Posted

技术标签:

【中文标题】p/invoke 方法返回空结构【英文标题】:p/invoke method returns empty struct 【发布时间】:2019-04-23 16:20:54 【问题描述】:

我有一个包含结构的 C++ 代码,我需要将它传递给 C#:

包装器.h

#pragma once
typedef struct

    int     int1;
    int     int2;
 MY_STRUCT;

MY_STRUCT mystruct;
extern "C" __declspec(dllexport) int __stdcall GetTestStruct(MY_STRUCT* cs_struct);

包装器.cpp:

int __stdcall GetTestStruct(MY_STRUCT* cs_struct)

    mystruct.int1 = 23;
    mystruct.int2 = 45;
    cs_struct = &mystruct;
    return 0;

包装器.cs:

class Program

  [StructLayout(LayoutKind.Sequential)]
  public struct MY_STRUCT
  
    public int int1;
    public int int2;
  

  [DllImport(VpxMctlPath)]
  public static extern int GetTestStruct(ref MY_STRUCT mystruct);

  static void Main(string[] args)
  
    var s = new MY_STRUCT();
    GetTestStruct(ref s);
  

运行此代码后,s 的 int1 和 int2 仍然为零。我试图将 C# 结构字段设为私有和公共,但没有区别。我查看了 C++/CLI,但这对于这个小任务来说似乎有点过分了。有没有简单的方法可以做到这一点?

【问题讨论】:

代码尽可能简单。您的代码不起作用,因为您需要使用以下方法在非托管内存空间中分配 c# 中的结构: IntPtr s = Marshal.AllocHGlobal(Marshal.SizeOf(myStruct));然后在 c++ 代码中,您必须将数据写入 cs_struct=>int1 = 23;和 cs_struct=>int2 = 45; @RyanWilson,它有效。作为答案提交。 @KevinS.Miller 已提交。很高兴它有帮助。 【参考方案1】:

更改您的 C++ 函数以直接在引用的结构上设置整数值:

int __stdcall GetTestStruct(MY_STRUCT* cs_struct)

    cs_struct->int1 = 23;
    cs_struct->int2 = 45;
    //cs_struct = *mystruct; //This line may not be necessary
    return 0;

【讨论】:

以上是关于p/invoke 方法返回空结构的主要内容,如果未能解决你的问题,请参考以下文章

从 p/invoke 修改结构布局

CPU 体系结构独立 P/Invoke:DllName 或路径可以是“动态的”吗?

P/Invoke:内存损坏与指针

使用 P/Invoke 时设置 StringBuilder.Capacity 的正确方法是啥?

使用 C# P/Invoke 方法在 Struct 内编组数组

使用 P/Invoke 从 Unity 高效地与非托管代码对话