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

标签 c# interop marshalling

我正在开发一个 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 成员。我不希望按值复制它,因为它将是大量数据,而且我不想复制内存...我如何确保不会发生这种情况?

感谢您的帮助。

最佳答案

最直接的问题是 ResultData 中的 Results 成员。 native 类型是 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)); }
} 

这是假设它是单个值。如果它不止一个值,则需要更复杂的编码。

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

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

关于C#/C++ 互操作 - 需要帮助定义我的数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1510664/

相关文章:

c# - 从 winform C# 通过命令行以编程方式运行 .dtsx 文件

java - 在 Frege 中使用 java.util.Properties

c# - 恢复另一个应用程序的最小化窗口

c++-cli - 从 C++/CLI 指针转换为 native C++ 指针

java - 使用 JAXB 在 Java 中编码

c# - 将结构编码(marshal)到指针时出现 "Attempted to read of write protected memory..."错误

python - XML-RPC - 无法编码递归字典

c# - 使用 FileStream.SafeFileHandle 后,删除对 GC.KeepAlive() 的调用是否安全?

c# - 为什么 Task.Factory.StartNew() 需要使用 CancellationToken 重载?

c# - Html Agility Pack 结束于不起作用