【问题标题】:C#/C++ interop - Need help defining my data structureC#/C++ 互操作 - 需要帮助定义我的数据结构
【发布时间】:2010-12-03 09:33:14
【问题描述】:

我正在开发一个 C# 应用程序,它试图使用通过 C++ DLL 提供的功能。我现在很难让 DLLImport 定义正常工作。

这是等式的 C++ 方面:

struct Result
{
    FLOAT   first;
    FLOAT   second;
};

struct ResultData
{
    UINT            uint1;
    UINT            uint2;
    Result          result;
    Result*         pResults;
};

#define DllImport __declspec(dllimport)    
extern "C"
{
    DllImport HRESULT APIENTRY Process(const PCWSTR FileName, const PCWSTR logfileFileName, const PCWSTR DataFileName, ResultData** ppResults);
    DllImport HRESULT APIENTRY Release(ResultData* pResults);
}

在 C# 方面,这是我目前所做的:

    [StructLayout(LayoutKind.Sequential)]
    public struct Result
    {
        public float first;
        public float second;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ResultData
    {
        public uint uint1;
        public uint uint2;
        public Result result;
        public Result[] Results;
    }    

        DllImport("MyDLL.dll")]
        static extern uint Release(ResultData pResults);

        [DllImport("MyDLL.dll")]
        static extern uint Process(string FileName, string logfileFileName, string DataFileName, ref ResultData ppResults);

这是正确的方法吗?我最关心的是 ResultData 结构的 pResults 成员。我不希望按值复制,因为这将是大量数据并且我不想复制内存......我如何确保不会发生这种情况?

感谢您的帮助。

【问题讨论】:

    标签: c# interop marshalling


    【解决方案1】:

    如果您可以将接口保留为纯 C 原始类型,则无需进行任何编组。这将为您省去很多心痛。

    【讨论】:

      【解决方案2】:

      最直接的问题是 ResultData 中的 Results 成员。本机类型是Result*,但您已将其转换为数组。这可能有效,也可能无效(不记得我的头顶)。不过,可以将其编组为 IntPtr 类型。

      [StructLayout(LayoutKind.Sequential)]
      public struct ResultData
      {
          public uint uint1;
          public uint uint2;
          public Result result;
          public IntPtr RawResults;
          public Result Results { get { return (Result)Marshal.PtrToStructure(RawResults,typeof(Result)); }
      } 
      

      这是假设它是一个单一的值。如果它有多个值,则需要更复杂的编组。

      本机 Release 方法也采用 ResultData*,但您在托管签名中有一个简单的值 ResultData 类型。它需要具有相同级别的间接性。您可以通过将其设为 ref 参数来实现此目的。

      DllImport("MyDLL.dll")]
      static extern uint Release(ref ResultData pResults);
      

      【讨论】:

      • 嗯,单值 == 一个值,afaict。我猜你在最后一句话中错过了“超过”
      • @Vinko,正确。在有人指出明显的不一致之前,它对自己的阅读效果令人惊讶:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多