带有指针到指针参数的 PInvoke 函数
PInvoke function with pointer to pointer parameter
你好,我正在用 C# 包装C++库。C++中的下一个函数:
SCREENCAPTUREDLL_API wchar_t** getAudioDeviceList(int* listSize) {
static std::vector<wchar_t*> descriptionList;
AudioCaptureList::getInstance().Update();
AudioCaptureList::getInstance().getList(&descriptionList);
*listSize = descriptionList.size();
return &descriptionList[0];
}
使用下一个 C# 代码包装:
[DllImport(screenCaptureDLLPath, CallingConvention = callConversion)]
private static extern IntPtr getAudioDeviceList(ref int arrayCount);
public static string[] GetAudioDeviceList()
{
IntPtr outputStr;
int length = 0;
outputStr = getAudioDeviceList(ref length);
string[] resultArray = new string[length];
for (int j = 0; j < length; j++)
{
resultArray[j] = Marshal.PtrToStringUni(Marshal.ReadIntPtr(outputStr, 4 * j));
}
return resultArray;
}
正如我预期的那样,这工作得很好,但我即将通过引用将值从函数本身更改为变量的方式,所以我将我的代码更改为:
C++
SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t** list, int* listSize) {
static std::vector<wchar_t*> descriptionList;
AudioCaptureList::getInstance().Update();
AudioCaptureList::getInstance().getList(&descriptionList);
*listSize = descriptionList.size();
list = &descriptionList[0];
}
C#
[DllImport(screenCaptureDLLPath, CallingConvention = callConversion)]
private static extern void getAudioDeviceList(out IntPtr listRef, ref int arrayCount);
public static string[] GetAudioDeviceList()
{
IntPtr outputStr;
int length = 0;
getAudioDeviceList(out outputStr, ref length);
string[] resultArray = new string[length];
for (int j = 0; j < length; j++)
{
resultArray[j] = Marshal.PtrToStringUni(Marshal.ReadIntPtr(outputStr, 4 * j));
}
return resultArray;
}
但是我得到错误,返回的内存地址为零。这里有什么问题?请帮助我了解导致问题的原因以及如何解决,谢谢!
为什么 Pinvoke 不起作用?因为您尝试将指向字符串的指针解释为指向一组字符串的指针。但是 PInvoke 并没有错 - 发生这种情况是因为新功能签名及其内部代码实际上存在问题。
看:
SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t** listRef, int* listSize);
无法提供相同的数据,例如
DLL_API wchar_t** getAudioDeviceList(int* listSize)
因为原始定义基本上返回了指向一组指向字符串的指针(我的意思是 C 样式字符串)的指针,而wchar_t** listRef
只能允许返回指向字符串的单个指针。
SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t** listRef, int* listSize)
{
...
*listRef = "string";
我不知道新版本的函数内部发生了什么(您没有显示代码),但是listRef = &descriptionList[0];
会编译,尽管不会做任何事情,即使*listRef = &descriptionList[0];
以某种方式编译,它也不会包含您想要的内容。
因此,函数签名应包含三重指针,以允许返回一组字符串。
SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t*** listRef, int* listSize)
{
...
*listRef = &descriptionList[0];
}
然后,您的 PInvoke 将正常工作,因为它将具有指向一组字符串指针的相同指针。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 带有指针到指针参数的 PInvoke 函数
- 带指针的PInvoke - c++到c#