C# 访问c+中带有char*参数的函数时发生AccessViolationException+;带C的动态链接库# 问题< /强>尝试在C++ DLL中使用以下原型……/P>中的函数 int-connectDfuBootloader(char*usbIndex)
…从C#,使用这些p/Invoke签名中的任何一个,会导致AccessViolationException:C# 访问c+中带有char*参数的函数时发生AccessViolationException+;带C的动态链接库# 问题< /强>尝试在C++ DLL中使用以下原型……/P>中的函数 int-connectDfuBootloader(char*usbIndex),c#,c++,C#,C++,…从C#,使用这些p/Invoke签名中的任何一个,会导致AccessViolationException: IntPtr [DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)] 专用静态外部int ConnectdFuotLoader(IntPtr usbIndex); 公共静态int-connectDfuBootloader(字符串usbIndex) { IntP
[DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)]
专用静态外部int ConnectdFuotLoader(IntPtr usbIndex);
公共静态int-connectDfuBootloader(字符串usbIndex)
{
IntPtr值=Marshal.StringToHGlobalAuto(usbIndex);
返回ConnectdBubootLoader(值);
}
[DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)]
publicstaticextern-int-connectDfuBootloader(字符串usbIndex);
[DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)]
公共静态外部连接数据仓库装载器(StringBuilder usbIndex);
[DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)]
public static extern int connectDfuBootloader([marshallas(UnmanagedType.LPStr)]字符串usbIndex);
[DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl,CharSet=CharSet.Ansi)]
publicstaticextern-int-connectDfuBootloader(字符串usbIndex);
有人能提供一些建议吗
我尝试过的其他事情
各种堆垛溢流柱,如
也尝试了自己的小C++ DLL,用于测试目的,包含一个与上面问题相同的签名:
int functionAlpha(char*a)
{
如果(a[0]=='a')
返回10;
其他的
返回20;
}
使用上述任何方法,我都可以从C#访问此函数,没有问题,例如
[DllImport(@“test.dll”,CallingConvention=CallingConvention.Cdecl)]
公共静态外部函数(字符串a);
这让我觉得“int-connectDfuBootloader(char*usbIndex)”函数有一些特殊之处。但是他们有相同的签名,为什么一个有效而另一个无效?我没有dll的源代码,因此无法查看其中是否有任何其他差异
更新-尝试了下面@Taekahn建议的C++/CLI包装,同样的事情强>
因此,我在C++/CLI包装器项目的标题中有这样的内容:
#包括“include/CubeProgrammer_API.h”
使用名称空间系统;
名称空间CLI
{
公共引用类CubeWrapper
{
公众:
int-wrappedconnectedfubootloader(字符串^a);
};
}
然后在包装器项目中的cpp文件中,我有:
namespace CLI
{
静态字符*字符串到字符数组(字符串^string)
{
char*str=(char*)(Marshal::StringToHGlobalAnsi(string)).topenter();
返回str;
}
int CubeWrapper::wrappedConnectedBubootLoader(字符串^a)
{
a=“USB0”;
//从我试图包装的链接C++ DLL调用函数
返回connectdBubootLoader(字符串_到数组(a));
}
}
它给出了相同的结果System.AccessViolationException!这到底是怎么回事
还尝试使用c++中的dll
使用C++程序对DLL进行相同的操作,运行良好。
证明DXIV是正确的;查看API提供的一些C++示例代码,并发现必须先设置几个回调。一旦我对它们进行了排序,问题就解决了。
我的建议是放弃pinvoke,并从C++/CLI包装器调用该函数。它比平沃克容易1000倍。除此之外,还有更多的错误消息吗?CallingConvention.Cdecl
可能应该是StdCall
。@Taekahn在异常消息中没有其他有用的东西。我将尝试您建议的C++/CLI包装方法。@dxiv尝试了StdCall,结果相同。@raml我没有dll的源代码
,因此您的选项目前非常有限。您可能猜错了签名,或者该函数依赖于首先调用的其他函数,或者可能有许多失败原因。很高兴您回答了自己的问题。必须首先调用“setDisplayCallbacks”,对吗?我不确定我是否发现了。附言:那个API太差劲了;D