1

在我决定在这里发布之前,我一直在阅读这个问题。我有需要在 C# 程序内部访问的 C dll。DLL 的代码非常简单。因为它只不过是生物识别驱动程序的一个钩子(它是 C,因为它必须包含驱动程序中的 lib 和头文件才能使代码工作)。这是dll的代码:

#include <stdio.h>
#include <windows.h>
#include <DPCN_TM.h>

__declspec(dllexport) unsigned char * ConvertPlatinumTemplateToDpTemplate(const unsigned char* inputData);

HRESULT Convert(
    const unsigned char* inputData,
    const size_t        size,
    DPCN_DATA_TYPE inputDataType,
    DPCN_DATA_TYPE outputDataType,
    DPCN_PURPOSE        purpose,
    unsigned char**     ppbOutputData,
    const void *        outputParameters,
    size_t *            pcbData)
{
    HRESULT hr = 0;
    size_t cbData = 0;
    if (FAILED(hr = DPCNConvertFingerprintData(inputData, size, inputDataType, purpose, NULL, outputDataType, outputParameters, NULL, &cbData))) {
        return hr;
    }

    if (!(*ppbOutputData = (unsigned char *)malloc(cbData))) {
        return DPCN_ERR_NO_MEMORY;
    }

    hr = DPCNConvertFingerprintData(inputData, size, inputDataType, purpose, NULL, outputDataType, outputParameters, *ppbOutputData, &cbData);

    *pcbData = cbData;
    return hr;
}


unsigned char * ConvertPlatinumTemplateToDpTemplate(const unsigned char* inputData) {
    HRESULT hr = 0;
    const size_t         inputSize = sizeof(inputData);
    DPCN_DATA_TYPE inputDataType  = DPCN_DT_DP_TEMPLATE;
    DPCN_DATA_TYPE outputDataType = DPCN_DT_DP_PLATINUM_TEMPLATE;
    unsigned char *pbOutputData = NULL;
    size_t cbData = 0;

    hr = Convert(inputData, inputSize, inputDataType, outputDataType, DPCN_PURPOSE_IDENTIFICATION, &pbOutputData, NULL, &cbData);

    return pbOutputData;
}

如您所见,DLL 的内容非常简单。从代码中你可以看到我需要在 C# 程序中访问这个函数。

unsigned char * ConvertPlatinumTemplateToDpTemplate(const unsigned char* inputData);

现在在我的 C# 代码中,我已经这样做了:

[DllImport(@"path_to_dll\DPFPTemplateConvert.dll")]
public extern byte[] ConvertPlatinumTemplateToDpTemplate(byte[] inputData);

当我调用该函数时,我最终收到此错误:

A first chance exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in DLLImportTest.exe
Additional information: Cannot marshal 'return value': Invalid managed/unmanaged type combination.

我究竟做错了什么?

4

1 回答 1

1

unsigned char * 不能转换为 .NET 字节数组,原因很简单:该数组的长度应该是多少?

即便如此,如果该指针指向该函数分配的内存,则将指针从函数中传递出来也是一个坏主意。谁来释放这段记忆?

您应该让 .NET 端为结果分配 byte[],并将其传递给函数。

如果.NET 端事先不知道分配的数组需要多大,请使用此处解释的回调:http: //blog.getpaint.net/2012/04/30/marshaling-native-arrays-back-as -managed-arrays-without-copying/

于 2013-09-19T13:29:53.830 回答