Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从c#捕获本机异常并在其离开作用域后获取异常.what()_C#_C++_Exception_Interop_Marshalling - Fatal编程技术网

从c#捕获本机异常并在其离开作用域后获取异常.what()

从c#捕获本机异常并在其离开作用域后获取异常.what(),c#,c++,exception,interop,marshalling,C#,C++,Exception,Interop,Marshalling,我从C#Mono调用一个本机dll,但我无法用try-catch子句C#side捕获异常。显然,Mono不支持这一点,不管设置了什么标志(根据其他关于这个问题的帖子)。Mono总是在异常离开本机端时关闭 我提出的解决方案是,用c#中的所有dll外部方法传递一个[Out]IntPtr errorText。这是作为字符**接收的本机端。本机C++函数将所有的内容打包在尝试catch(const STD::Extand EX)< /Cord>子句中。如果没有异常,我将errorText设置为nullp

我从C#Mono调用一个本机dll,但我无法用try-catch子句C#side捕获异常。显然,Mono不支持这一点,不管设置了什么标志(根据其他关于这个问题的帖子)。Mono总是在异常离开本机端时关闭

我提出的解决方案是,用c#中的所有dll外部方法传递一个
[Out]IntPtr errorText
。这是作为字符**接收的本机端。本机C++函数将所有的内容打包在<代码>尝试catch(const STD::Extand EX)< /Cord>子句中。如果没有异常,我将errorText设置为nullptr,但如果有异常,我将其设置为
*errorText=ex.what()

当本机调用返回时,它或者有一个指向error的null指针,这意味着没有异常,或者它是非null的,在这种情况下,我将其提取为
Marshal.PtrToStringAnsi(errorText)

这是可行的,也不可行。捕获异常并设置指针,但封送处理调用从IntPtr返回null。经过一些测试后,我意识到如果我将本机错误文本指针设置为一个常量,如
*errorText=“a test”
,那么它就会正常工作

问题似乎是,当本机函数返回时,本机异常对象超出范围,此时
what()
文本无效,这意味着当我试图封送指向它的指针的内容时,它无效

一种解决方案是,我自己总是将常量字符串作为异常抛出,比如
抛出“不好的东西”
并捕获它,因为这些常量字符串仍然有效,然后捕获其他
std::exception
s只返回一个通用错误字符串,比如“undefined std::exception”

这显然不是完美的,尽管它可以工作。问题是为什么我在离开函数后无法访问
*what()
。虽然实际的异常对象可能超出范围,但创建它时使用的消息本身通常是常量。如果我抛出
std::exception(“something”)
那么
what
应该指向常量“something”,并且在异常超出范围后应该保持有效

我曾考虑在dll中创建一个持久化的字符数组,并将what()复制到其中以供以后检索,但我需要支持多个同时访问,这可能会同时出现多个异常,从而导致t争夺此缓冲区

我非常感兴趣的是,如果有人对异常离开作用域后为什么
what()
不可用有所了解,或者是一个比抛出字符串异常更优雅的解决方法


编辑:另一种解决方案是为错误消息管理端分配字符串,并传递指向该字符串的指针,以便本机端将错误放入其中。我只是不需要每次调用都分配一个新字符串。。。您更希望只在what()中获取一个指向实际消息的指针,您可以为“errorText”参数分配一个字符缓冲区(在本机DLL中),并将文本“ex.what()”复制到该缓冲区。在这种情况下,内存将保持有效。
但我认为,在读取C#中的字符串后,您必须自己释放char缓冲区,以防止内存泄漏。

可能相关。()可能是解决方案:()这看起来确实相关,但我不能从我的本机代码中抛出异常,就像在引用的文章中一样。这会导致即时终止,而且我也无法分配从本机代码中为消息收集的垃圾。。。这是纯C++,没有MS的添加。不过,给我一个主意吧,所以我会延长我的职位。我很好奇为什么这次投票被否决了。这似乎是一个没有简单解决方案的一般问题…?谢谢,但根据我的问题,我已经考虑并拒绝了。我对你的回答有点不公平,因为你实际上没有说缓冲区应该在所有通话中共享。我现在使用的解决方案是为每个异常分配缓冲区,并将指针传递回托管。然后,Managed的任务是在读取文本后调用该指针上的本机delete。因此,我显然应该接受你的回答。如果我一开始误解了你,很抱歉。