我正在开发一个 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/