使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
AccessViolationException when accessing function with char * argument in c++ dll with C#
问题尝试使用以下原型的c++dll中的函数。。。
int connectDfuBootloader(char * usbIndex)
从C#,使用这些P/Invoke签名中的任何一个,都会导致AccessViolationException:
- IntPtr
[DllImport(@"CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int connectDfuBootloader(IntPtr usbIndex);
public static int connectDfuBootloader(string usbIndex)
{
IntPtr value = Marshal.StringToHGlobalAuto(usbIndex);
return connectDfuBootloader(value);
}
- 字符串
[DllImport(@"CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int connectDfuBootloader(string usbIndex);
- StringBuilder
[DllImport(@"CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int connectDfuBootloader(StringBuilder usbIndex);
- 马歇尔主题变奏曲,尝试LPStr、LPTStr等
[DllImport(@"CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int connectDfuBootloader([MarshalAs(UnmanagedType.LPStr)]string usbIndex);
- 指定字符集、ANSI、Unicode等主题的变体
[DllImport(@"CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl, CharSet =CharSet.Ansi)]
public static extern int connectDfuBootloader(string usbIndex);
有人能提出什么建议吗?
我尝试过的其他东西
各种StackOverflow帖子,例如使用C#访问非托管C++DLL时发生AccessViolationException
此外,出于测试目的,我尝试制作自己的小型C++dll,其中包含一个与上面的问题具有相同签名的函数:
int functionAlpha(char * a)
{
if (a[0] == 'a')
return 10;
else
return 20;
}
我可以使用上面的任何方法,例如,毫无问题地从C#访问这个功能
[DllImport(@"test.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int functionAlpha(string a);
这让我觉得"int connectDfuBootloader(char*usbIndex("函数有一些特别之处。但他们有相同的签名,为什么一个有效,另一个无效?我没有dll的源代码,所以不能在那里查看是否有任何其他差异。
更新-按照@Taekahn下面的建议,尝试了C++/CLI包装,同样的事情
因此,我在C++/CLI包装器项目的标题中有这样的内容:
#include "include/CubeProgrammer_API.h"
using namespace System;
namespace CLI
{
public ref class CubeWrapper
{
public:
int wrappedConnectDfuBootloader(String^ a);
};
}
然后在包装器项目中的一个cpp文件中,我有:
namespace CLI
{
static char* string_to_ncchar_array(String^ string)
{
char* str = (char*)(Marshal::StringToHGlobalAnsi(string)).ToPointer();
return str;
}
int CubeWrapper::wrappedConnectDfuBootloader(String^ a)
{
a = "USB0";
// Calls the function from the linked c++ dll I'm trying to wrap
return connectDfuBootloader(string_to_ncchar_array(a));
}
}
它给出了相同的结果,System.AccessViolationException!这里可能发生了什么?
还尝试使用c++中的dll尝试使用c++应用程序中的dll执行相同的操作序列,效果良好。
原来dxiv是正确的;查看了API提供的一些c++示例代码,发现必须首先设置几个回调。一旦我整理了这些,问题就解决了。
相关文章:
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 当从函数参数中的临时值调用复制构造函数时
- 如何从"decltype()"获取函数参数的数量<funtion>?
- 如何将lambda作为模板类的成员函数参数
- 模板参数推导失败,函数参数/参数不匹配
- 如何在C++中将迭代器作为函数参数传递
- 将函数参数"const char*"转换为"std::string_view"是
- C++ 如何将数组值解压缩为函数参数
- 主函数参数的属性
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何定义在用作函数参数时工作的类模板的转换
- 将函数参数完美转发到函数指针:按值传递呢?
- 为什么我不能将引用作为 std::async 的函数参数传递
- 什么..(省略号)作为函数原型中唯一的函数参数,C++?
- 是否可以就地构造一个固定大小的数组作为函数参数?
- 接受模板作为函数参数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- Arduino 函数参数