【问题标题】:Struct from C++ to C#从 C++ 到 C# 的结构
【发布时间】:2013-11-22 11:33:17
【问题描述】:

我有一个项目使用的库主要是基于 C++ 构建的。 带有这个库的交付的 DLL,我已经导入到我的 C# 项目中。 在 Unity 中导入以下方法后:

    [DllImport("pst")]
private static extern int pst_get_sensor(PSTSensor sensor);

我需要这个 PSTSensor 结构,所以实际使用该方法。 在 C++ .h 文件中,结构定义为:

struct PSTSensor
{
        char    name[80];       /**< Device name */
        int     id;             /**< Device identifier (for other tracking interfaces */
        float   pose[16];       /**< Device pose estimate as row-major matrix */
        double  timestamp;      /**< Time the data was recorded */
};

我尝试在 C# 中复制它,结果如下:

    struct PSTSensor{
    PSTSensor(char[] name, int id, float[] pose, double timestamp){
        this.name = name;
        this.id = id;
        this.pose = pose;
        this.timestamp = timestamp;
    }
    public char[] name;
    public int id;
    public float[] pose;
    public double timestamp;
}

在这个项目附带的示例 C++ 代码中,声明调用 pst_get_sensor(&amp;sensor) 这个“&”符号,我不认识?我将如何在 C# 中调用此方法并使其工作?

我想我毁了这个结构,看看我以前从未和他们一起工作过。至少它不再在编译时抛出错误,但我认为它仍然是错误的。有什么想法吗?

提前非常感谢, 笑脸

【问题讨论】:

    标签: c# c++ pinvoke


    【解决方案1】:

    我不确定我是否完全回答了您的问题,但在 c++ 中,& 用于通过引用传递参数,这意味着您传入的参数可以在函数内部进行操作。在我看来,原始函数似乎用于填充传感器结构。

    int C# 你可以使用 ref 或 out 关键字通过引用传递:

    private static extern int pst_get_sensor(PSTSensor ref sensor);
    

    为什么在 C# 实现中添加构造函数?

    【讨论】:

    • 这已经很有帮助了,我添加了一个构造函数,因为我不确定如何在没有它的情况下以固定大小定义数组。我尝试了不同的方法,但大多只是向我抛出错误。
    • 'private static extern int pst_get_sensor(PSTSensor ref sensor);'这给出了错误:需要标识符,'ref' is a keyword。
    • 对不起,我认为 ref 关键字实际上应该排在第一位:(ref PSTSensor sensor)。查看 C# 参考资料,也许它会帮助您更好地理解 C# 中的引用传递:msdn.microsoft.com/en-us/library/vstudio/0f66670z.aspx
    • 是的,这似乎解决得恰到好处!您对正确使用结构有任何想法吗?我还找不到很多好的例子。
    • “正确使用结构”是什么意思?
    【解决方案2】:

    你需要做的就是将参数声明为 ref

    private static extern int pst_get_sensor(ref PSTSensor sensor);
    

    如果你想看一个例子,有一个here

    【讨论】:

      【解决方案3】:

      你没有显示你的函数的 C++ 声明,但你这样称呼它:

      pst_get_sensor(&sensor);
      

      大概是这样声明的:

      int pst_get_sensor(PSTSensor *sensor);
      

      函数接收一个指向结构的指针。这很清楚,因为调用使用了&amp; 运算符,该运算符获取对象的地址。

      在 C# 端,您将此参数转换为 ref 参数。像这样:

      [DllImport(...)]
      static extern int pst_get_sensor(ref PSTSensor sensor);
      

      现在,您的另一个问题是您的结构声明不正确。它包含内联数组,您必须将这些数组的长度传达给编组器。像这样:

      [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
      struct PSTSensor
      {
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
          public string name;
          public int id;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
          public float[] pose;
          public double timestamp;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        相关资源
        最近更新 更多