C# 访问c+中带有char*参数的函数时发生AccessViolationException+;带C的动态链接库# 问题< /强>尝试在C++ DLL中使用以下原型……/P>中的函数 int-connectDfuBootloader(char*usbIndex)

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

…从C#,使用这些p/Invoke签名中的任何一个,会导致AccessViolationException:

  • IntPtr
  • [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);
    
  • StringBuilder
  • [DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)]
    公共静态外部连接数据仓库装载器(StringBuilder usbIndex);
    
  • 马绍拉斯主题变奏曲,LPStr,LPTStr等
  • [DllImport(@“CubeProgrammer_API.dll”,CallingConvention=CallingConvention.Cdecl)]
    public static extern int connectDfuBootloader([marshallas(UnmanagedType.LPStr)]字符串usbIndex);
    
  • 关于指定字符集、ANSI、Unicode等主题的变体
  • [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