【发布时间】:2017-08-17 18:39:53
【问题描述】:
这是我试图调用的方法签名。
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);
我的方法没有失败,但它没有返回数据中的任何内容。知道如何从 C# 调用这个奇怪的方法吗?
【问题讨论】:
-
你有没有尝试调用任何更简单的函数?还是明确设置调用约定?
[DllImport("DataGetter.dll", CallingConvention = CallingConvention.Cdecl)] -
我过去曾使用 P/Invoke 和简单的函数,但是,关于这个 DLL,这是它公开的唯一方法。有趣的是,当我添加调用约定时,调用失败并出现以下错误。 “QueryData 使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。请检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。”
-
我已经很久没有做任何 p/invoke 了,但我认为你的问题是“数据”成员。该函数正在接受 BYTE**(不是 BYTE*)。显然,它在内部分配了一个缓冲区,并返回一个指向缓冲区的指针及其大小。除非你在调用后做一些清理工作,否则你很可能会导致内存泄漏。
-
是的,你打算如何释放内存?是在 COM 堆上分配的吗?
-
不确定如何释放内存?你知道从 C# 代码本身中释放的方法吗?这足够 Marshal.DestroyStructure(data, typeof(IntPtr)); 吗?