【问题标题】:AccessViolationException calling native C++ code from managed C++ (wrapper for ASP.NET)AccessViolationException 从托管 C++(ASP.NET 的包装器)调用本机 C++ 代码
【发布时间】:2018-02-07 08:29:56
【问题描述】:

我有一个 ASP.NET Web 应用程序,它需要访问本机 C++ DLL 中的函数。为此,我使用托管 C++ DLL 包装了本机 C++ 代码。但是,从托管代码调用本机函数会导致 System.AccessViolationException。我不必使用本机代码,但它会写入文件系统(日志),这是我的第一个猜测,但根据其他 SO 答案,AccessViolationException 是由内存问题引起的。

代码很简单,这是精简版:

#include <msclr\marshal_cppstd.h>

#define AS_NATIVE_STRING(managed_string) msclr::interop::marshal_as<std::string>(managed_string)
#define AS_MANAGED_STRING(native_string) msclr::interop::marshal_as<String^>(native_string)

ReturnStruct ManagedClass::execute_managed(String ^param1, String ^param2)
{
    auto param1_native = AS_NATIVE_STRING(param1);
    auto param2_native = AS_NATIVE_STRING(param2);

    // here I get the exception:
    auto result = _wrapped_api->execute_native(param1_native, param2_native);

    if (is_error_string(result.first))
        throw gcnew System::Exception(AS_MANAGED_STRING(result.second));

    auto result1 = AS_MANAGED_STRING(result.first);
    auto result2 = AS_MANAGED_STRING(result.second);
    return ReturnStruct(result1, result2);
}

关于可能导致它的任何提示?我确实看过类似的问题,但似乎没有一个答案真正适合我的问题。

编辑: 使用HandleProcessCorruptedStateExceptionsAttribute,我能够确定AccessViolationException 的错误消息:“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”

【问题讨论】:

  • 尝试使用 std::wstring 代替 std::string。
  • 这不是一个真正的选择,因为包装的代码只接受std::string,我无法改变它。除此之外,根据docs.microsoft.com/cpp/dotnet/overview-of-marshaling-in-cppstd::stringSystem::String^ 之间的转换是有效的。是的,我可能会从System::String^ 转换为std::wstring,然后再转换为std::string,但我不想碰std::wstring,所以你能告诉我你的建议背后的原因吗?这只是一个疯狂的猜测还是一个有根据的建议?
  • 只是字符串由 16 位字符组成。好的,如果您保留 std ASCII 集,但除此之外的任何内容,并且您使用 utf-8/wchars 等。此代码是在其自己的文件中还是大型托管 C++ 代码的一部分?托管/非托管的东西通常需要在一个单独的源文件中。我从来没有找到原因,但通常有效。
  • 这可能是真的,但我刚刚验证,编组到多字节字符串也适用于非 ASCII 字符,或者基本上:这可以正常工作。整个 DLL 仅包含 6 个混合托管代码和本机代码的函数,所以是的,您可以说它们位于单独的文件中。

标签: c++ managed-c++


【解决方案1】:

经过进一步调查,我得出的结论是,我基本上无法解决这个问题。我自己创建了 DLL 的模拟版本,以便能够介入并查看类型转换是否正确以及参数是否包含正确的字符串。情况就是这样。这并没有真正帮助我,但也许其他人可能会在他/她的代码中发现这种方法的问题。

我会联系包装 api 的作者。

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多