从c#中捕获本地异常,并在它离开作用域后获取exception. .()
Capturing native exception from c# and getting the exception.what() after it leaves scope
我从c# Mono调用一个本地dll,我不能用c#端try catch子句捕获异常。显然Mono不支持这一点,不管设置了哪些标志(根据这里关于这个问题的其他帖子)。当异常离开本机时,Mono总是会关闭。
解决方案,我想出了,是通过一个[Out]IntPtr errorText
与我所有的dll外部方法从c#。这是作为char**接收的本机。本地c++函数将所有内容包装在try catch(const std::exception& ex)
子句中。如果没有异常,我将errorText设置为nullptr,但如果有异常,我将其设置为*errorText=ex.what()
当本机调用返回时,它要么有一个指向错误的空指针,这意味着没有异常,要么是非空的,在这种情况下,我将其提取为Marshal.PtrToStringAnsi(errorText)
这个工作和不工作。异常被捕获,指针被设置,但是marshal调用从IntPtr返回null。经过一些测试,我意识到,如果我将本机错误文本指针设置为像*errorText="a test"
这样的常量,那么它就会按预期工作。
问题似乎是本机异常对象在本机函数返回时超出作用域,此时what()
文本无效,这意味着当我试图从指针封送内容到它时它是无效的。
一个解决方案是总是自己抛出const字符串作为异常,如throw "something bad"
和捕获,因为这些常量字符串仍然有效,然后捕获其他std::exception
返回只是一个通用的错误字符串,如"undefined std::exception"。
这显然是不完美的,尽管它可以工作。问题是为什么在离开函数后我无法到达*what()
。虽然实际的异常对象可能超出作用域,但创建它的消息本身通常是一个常量。如果我抛出std::exception("something")
,那么what
应该指向常数"某事",并且在异常超出作用域后应该仍然有效。
我考虑过在dll中创建一个持久的字符数组,并将what()复制到其中以供以后检索,但我需要支持多个同时访问,这可能同时产生多个异常,导致t争夺这个缓冲区。
我很感兴趣,如果有人有一些见解,为什么what()
是不可用的异常离开作用域或一个好主意解决这个问题更优雅比抛出字符串异常。
编辑:另一种解决方案是为错误消息托管端分配字符串,并传递一个指向本机端的指针,以便将错误放入其中。我只需要不分配一个新的字符串每次调用…我更喜欢在what()
您可以为您的"errorText"参数分配一个字符缓冲区(在本机DLL中),并将文本"ex. .()"复制到该缓冲区。在这种情况下,内存将保持有效。但是我认为,在c#中读取字符串后,您必须自己释放字符缓冲区,以防止内存泄漏。
- 未在作用域中声明unordered_map
- 有没有一种方法可以在编译时获得作用域类名
- C++quit()函数中可能存在作用域问题
- 未在此作用域OpenCV3.4中声明cvSaveImage
- 全局作用域中函数指针的赋值
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 是同一作用域的函数部分中的函数调用
- 我的boost managed_shared_memory在离开作用域时似乎不会从内存空间中取消映射
- 即使在离开作用域后,如何访问在堆上分配的变量C++?
- c++ 指针在离开作用域后不会停留
- 空的唯一指针在离开作用域时调用析构函数
- 为什么离开作用域后仍然有对结构的有效访问
- C++11 Lambda闭包通过引用涉及一个堆栈变量,该变量离开作用域是允许的,但得到了未定义的行为
- 强制对象释放/离开作用域以调用析构函数
- 当future离开作用域时,线程要去哪里?
- 离开作用域时没有调用析构函数
- 从c#中捕获本地异常,并在它离开作用域后获取exception. .()
- C++二进制树编程新节点离开作用域问题
- 离开作用域时调用函数