C# 异常信息:调用C+时System.AccessViolationException异常+;动态链接库 我想让一个非托管C++ DLL与我的C项目合作,当程序通过VS2019中的调试器运行时,代码工作。当运行没有调试器时,应用程序崩溃时运行,事件查看器在调用C++ DLL 时给我异常信息:Stase.Access违规事件

C# 异常信息:调用C+时System.AccessViolationException异常+;动态链接库 我想让一个非托管C++ DLL与我的C项目合作,当程序通过VS2019中的调试器运行时,代码工作。当运行没有调试器时,应用程序崩溃时运行,事件查看器在调用C++ DLL 时给我异常信息:Stase.Access违规事件,c#,c++,pinvoke,dllimport,dllexport,C#,C++,Pinvoke,Dllimport,Dllexport,我已经尝试过改变我使用p/invoke的方式,改变我认为可以使它工作的方式。C++不是我的特长,但是DLL不是什么复杂的东西,只是一个if语句返回字符串。 有人能看出我哪里出了问题吗?或者提供有关如何解决此问题的提示 C# C++ (我知道这个问题已经被问过好几次了,在网上搜索之后,我还没有找到任何能帮助我的东西。) 编辑 dll和Project都是x86,同一个NETFramework < p>不能使用pNoCKE返回一个C++对象,如 STD::String 。有多种选项可用于使用pinv

我已经尝试过改变我使用p/invoke的方式,改变我认为可以使它工作的方式。C++不是我的特长,但是DLL不是什么复杂的东西,只是一个if语句返回字符串。 有人能看出我哪里出了问题吗?或者提供有关如何解决此问题的提示

C#

C++

(我知道这个问题已经被问过好几次了,在网上搜索之后,我还没有找到任何能帮助我的东西。)

编辑


dll和Project都是x86,同一个NETFramework

< p>不能使用pNoCKE返回一个C++对象,如<代码> STD::String 。有多种选项可用于使用pinvoke向调用者返回文本:

  • 返回一个COM BSTR
  • 返回被调用方分配的C字符串。调用方将需要取消分配它。通过使用共享堆或导出deallocator函数
  • 让调用者分配文本缓冲区,并让被调用者填充它
  • websearch很容易找到所有这些方法的示例


    我假设您的代码是一个简化的示例,但是如果您真的想指出成功或失败,那么您可以通过返回布尔类型来完全回避这个问题。

    谢谢大家的评论,实际上我有点笨

    C++必须是BOOL而不是BOOL

    c#做个傻瓜很好

    现在有一个新的问题,但进展


    再次感谢。

    您是否检查了程序是否可以访问DLL文件?我的意思是,DLL文件是否位于程序无需任何特殊权限即可加载的位置?另外,通过调用本地代码,你想达到什么目的?你有什么理由这么做?从DLL函数返回一个<代码>:ST::String < /C> >即使语言调用C++,也更不可能失败,更不用说C。你的函数的唯一方法是调用语言是C++,并且调用你的函数的应用程序是用同一个构建选项用同一个C++编译器构建的,运行库是DLL版本。基本上,该程序是一个审计工具,主程序的一个要求是用户CPU支持指令集SSE4.1-我认为实现这一点的唯一现实方法是通过使用CPUIDStop返回类型(仅由
    C++
    知道),例如
    bool
    。C++中的 BoOL <代码>与C语言中的<代码>布尔O/COD>不一样。C++中的 BOOL 具有由编译器使用的大小。例如,您应该使用已知大小的已知类型,例如
    int32\u t
    (32位int)。或者,在这种情况下,OP可以简单地返回
    bool
    ,而不是使用bool字符串化的true/false,同样的错误-我会查看返回的COM BSTRNo,不要。如果您只需要一个布尔值,请这样做。同样的错误最有可能发生,因为 Boo.<代码>也是C++类型,只有C++编译器使用它。实际上,你可以告诉封送器在C++中使用C++ BooL。我认为
    BOOL
    实际上是最简单的方法this@DavidHeffernan是的,我只是再检查一遍,你可以做到。。。但它不能保证便携。
    [DllImport("unmanaged.dll", EntryPoint = "checkCPU", CallingConvention = CallingConvention.Cdecl)]
            private static extern IntPtr checkCPU();
    
    // to call it
    
     string check = Marshal.PtrToStringAnsi(checkCPU());
    
    
    extern "C" __declspec(dllexport) std::string checkCPU()
    {
    
        if (InstructionSet::SSE41() || InstructionSet::SSE42()) {
            return "true";
        }
        else {
            return "false";
        }
    
    }