C# 调用 C++ DLL 传递指针到指针参数 [英] C# call C++ DLL passing pointer-to-pointer argument

查看:25
本文介绍了C# 调用 C++ DLL 传递指针到指针参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你们能帮我解决以下问题吗?我有一个 C++ 函数 dll,它将被另一个 C# 应用程序调用.我需要的功能之一如下:

Could you guys please help me solve the following issue? I have a C++ function dll, and it will be called by another C# application. One of the functions I needed is as follow:

struct DataStruct
{
    unsigned char* data;
    int len;
};

DLLAPI int API_ReadFile(const wchar_t* filename, DataStruct** outData);

我用 C# 编写了以下代码:

I wrote the following code in C#:

class CS_DataStruct
{
    public byte[] data;
    public int len;
}

[DllImport("ReadFile.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private static extern int API_ReadFile([MarshalAs(UnmanagedType.LPWStr)]string filename, ref CS_DataStruct data);

不幸的是,上面的代码不起作用......我猜这是由于 C++ func 需要一个指向 DataStruct 的指针,而我刚刚传入了一个 CS_DataStruct 的引用.

Unfortunately, the above code is not working... I guess that is due to the C++ func takes a pointer-to-pointer of DataStruct, while I just passed a reference of CS_DataStruct in.

我可以知道如何将指针到指针传递给 C++ func 吗?如果不可能,有什么解决方法吗?(C++ API 是固定的,因此无法将 API 更改为指针)

May I know how can I pass a pointer-to-pointer to the C++ func? If it is not possible, is there any workaround? (the C++ API is fixed, so changing API to pointer is not possible)

DataStruct 的内存将由 c++ 函数分配.在此之前,我不知道数据数组应该有多大.(感谢下方的评论)

Memory of DataStruct will be allocated by c++ function. Before that, I have no idea how large the data array should be. (Thanks for the comments below)

推荐答案

我使用了以下测试实现:

I used the following test implementation:

int API_ReadFile(const wchar_t* filename, DataStruct** outData)
{
    *outData = new DataStruct();
    (*outData)->data = (unsigned char*)_strdup("hello");
    (*outData)->len = 5;
    return 0;
}

void API_Free(DataStruct** pp)
{
    free((*pp)->data);
    delete *pp;
    *pp = NULL;
}

访问这些函数的 C# 代码如下:

The C# code to access those functions are as follows:

[StructLayout(LayoutKind.Sequential)]
struct DataStruct
{
    public IntPtr data;
    public int len;
};

[DllImport("ReadFile.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
unsafe private static extern int API_ReadFile([MarshalAs(UnmanagedType.LPWStr)]string filename, DataStruct** outData);

[DllImport("ReadFile.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe private static extern void API_Free(DataStruct** handle);

unsafe static int ReadFile(string filename, out byte[] buffer)
{
    DataStruct* outData;
    int result = API_ReadFile(filename, &outData);
    buffer = new byte[outData->len];
    Marshal.Copy((IntPtr)outData->data, buffer, 0, outData->len);
    API_Free(&outData);
    return result;
}

static void Main(string[] args)
{
    byte[] buffer;
    ReadFile("test.txt", out buffer);
    foreach (byte ch in buffer)
    {
        Console.Write("{0} ", ch);
    }
    Console.Write("
");
}

数据现在安全地传输到buffer,应该没有内存泄漏.我希望它会有所帮助.

The data is now transferred to buffer safely, and there should be no memory leaks. I wish it would help.

这篇关于C# 调用 C++ DLL 传递指针到指针参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆