努力使用 C# 从本机 DLL 调用方法
Struggling to call the method from native DLL using C#
这是我尝试调用的方法签名。
EXTERN_C
HRESULT
QueryData(
_Outptr_opt_result_bytebuffer_(*SizeOfData) PBYTE * Data,
_Out_opt_ UINT32* SizeOfData,
_In_ BOOL IsDataType
)
以上方法不是我的代码,它是供应商代码,不幸的是我没有足够的知识来调用这个方法。我所知道的是它应该给我一大堆数据。
这是我到目前为止所做的。
[DllImport("DataGetter.dll")]
internal static extern int QueryData(IntPtr data, UIntPtr sizeOfData, bool isDataType);
IntPtr data= new IntPtr();
UIntPtr sizeOfData= new UIntPtr();
bool isDataType= true;
int hresult = QueryData(data, sizeOfData, isDataType);
我的方法没有失败,但 return 数据中没有任何内容。知道如何从 C# 调用这个奇怪的方法吗?
这里有两个问题:首先是将 QueryData
设置的值放入 Data
和 sizeOfData
,这会得到指向局部变量的指针。您可以使用 ref
或 out
关键字来完成,因此 C++ 中的 UINT32* SizeOfData
变为 ref System.UInt32 SizeOfData
。 Key difference 之间的是 out
参数不必在函数调用之前初始化。其次是将 C++ 中定义的非托管数组转移到 C# 中。你可以用 Marshall.Copy
.
有一件事仍然不清楚,但应该在文档中说明 - 无论何时从 C++ 返回的数组都是动态分配的,并且需要在 C# 中释放或不需要。如果是这样,您将发生内存泄漏,每次调用函数都会增加内存使用量。最简单的测试方法是调用函数 1000000 次并检查内存使用情况。
完整代码:
[DllImport("DataGetter.dll"]
internal static extern int QueryData(out IntPtr data, out System.UInt32 sizeOfData, bool isDataType);
void example()
{
IntPtr dataPtr;
System.UInt32 sizeOfData;
bool isDataType = false;
int hresult = QueryData(out dataPtr, out sizeOfData, isDataType);
var data = new byte[sizeOfData];
Marshal.Copy(dataPtr, data, 0, (int)sizeOfData);
// data now contains retreived bytes
}
旧 POST:
试试。
[DllImport("DataGetter.dll")]
internal static extern int QueryData(ref IntPtr data, ref System.UInt32 sizeOfData, bool isDataType);
我不确定 PBYTE
是什么,但我想它是指向 BYTE 的指针。
函数应更改 data
和 sizeOfData
变量。
这是我尝试调用的方法签名。
EXTERN_C
HRESULT
QueryData(
_Outptr_opt_result_bytebuffer_(*SizeOfData) PBYTE * Data,
_Out_opt_ UINT32* SizeOfData,
_In_ BOOL IsDataType
)
以上方法不是我的代码,它是供应商代码,不幸的是我没有足够的知识来调用这个方法。我所知道的是它应该给我一大堆数据。
这是我到目前为止所做的。
[DllImport("DataGetter.dll")]
internal static extern int QueryData(IntPtr data, UIntPtr sizeOfData, bool isDataType);
IntPtr data= new IntPtr();
UIntPtr sizeOfData= new UIntPtr();
bool isDataType= true;
int hresult = QueryData(data, sizeOfData, isDataType);
我的方法没有失败,但 return 数据中没有任何内容。知道如何从 C# 调用这个奇怪的方法吗?
这里有两个问题:首先是将 QueryData
设置的值放入 Data
和 sizeOfData
,这会得到指向局部变量的指针。您可以使用 ref
或 out
关键字来完成,因此 C++ 中的 UINT32* SizeOfData
变为 ref System.UInt32 SizeOfData
。 Key difference 之间的是 out
参数不必在函数调用之前初始化。其次是将 C++ 中定义的非托管数组转移到 C# 中。你可以用 Marshall.Copy
.
有一件事仍然不清楚,但应该在文档中说明 - 无论何时从 C++ 返回的数组都是动态分配的,并且需要在 C# 中释放或不需要。如果是这样,您将发生内存泄漏,每次调用函数都会增加内存使用量。最简单的测试方法是调用函数 1000000 次并检查内存使用情况。
完整代码:
[DllImport("DataGetter.dll"]
internal static extern int QueryData(out IntPtr data, out System.UInt32 sizeOfData, bool isDataType);
void example()
{
IntPtr dataPtr;
System.UInt32 sizeOfData;
bool isDataType = false;
int hresult = QueryData(out dataPtr, out sizeOfData, isDataType);
var data = new byte[sizeOfData];
Marshal.Copy(dataPtr, data, 0, (int)sizeOfData);
// data now contains retreived bytes
}
旧 POST: 试试。
[DllImport("DataGetter.dll")]
internal static extern int QueryData(ref IntPtr data, ref System.UInt32 sizeOfData, bool isDataType);
我不确定 PBYTE
是什么,但我想它是指向 BYTE 的指针。
函数应更改 data
和 sizeOfData
变量。