C#/ C ++互操作 - 需要帮助定义我的数据结构

时间:2009-10-02 16:39:34

标签: c# interop marshalling

我正在尝试使用通过C ++ DLL提供的功能的C#应用​​程序。我现在有点困难让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成员。我不希望按值复制,因为它将是大量数据,我不想复制内存......我怎样才能确保不会发生?

感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

跳出来的最直接的问题是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类型。它需要具有相同的间接级别。您可以通过将其作为参考参数来实现此目的。

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

答案 1 :(得分:0)

如果您可以将接口保持为纯C基元类型,则不必进行任何编组。这将为你节省很多心痛。