我正在尝试使用通过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成员。我不希望按值复制,因为它将是大量数据,我不想复制内存......我怎样才能确保不会发生?
感谢您的帮助。
答案 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基元类型,则不必进行任何编组。这将为你节省很多心痛。