努力使用C#从本机DLL调用该方法

时间:2017-08-17 18:39:54

标签: c# c++ .net pinvoke

这是我试图调用的方法签名。

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#中调用这个奇怪的方法吗?

1 个答案:

答案 0 :(得分:2)

这里有两个问题:第一个是将QueryData设置的值设置为DatasizeOfData,它们可以获取指向局部变量的指针。您可以使用refout关键字进行操作,因此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
    }

旧帖子: 试试。

    [DllImport("DataGetter.dll")]
    internal static extern int QueryData(ref IntPtr data, ref System.UInt32 sizeOfData, bool isDataType);

我不确定PBYTE是什么,但我想它是指向BYTE的指针。 功能应更改datasizeOfData变量。