Я вызываю родную dll из C# Mono, и я не могу захватить исключения с предложением try catch C#. Очевидно, Mono не поддерживает это, независимо от установленных флагов (как в соответствии с другими сообщениями здесь об этой проблеме). Моно всегда будет просто закрываться, как только исключение покинет родную сторону.Захват собственного исключения из C# и получение исключения. What() после его удаления.
Решение, которое я придумал, состоит в том, чтобы передать [Out]IntPtr errorText
со всеми методами exll exll из C#. Это получает родную сторону как char **. Нативная функция C++ завершает все в статье try catch(const std::exception& ex)
. Если нет исключения, я устанавливаю errorText в значение nullptr, но если есть исключение, я устанавливаю его в *errorText=ex.what()
Когда внутренний вызов возвращается, он либо имеет нулевой указатель на ошибку, что означает исключение, либо не равно нулю в этом случае я извлекаю его как Marshal.PtrToStringAnsi(errorText)
Это работает и не работает. Исключения попадают и указатель устанавливается, но вызов маршала возвращает null из IntPtr. После некоторого тестирования я понимаю, что если я установлю собственный указатель текста ошибки на константу, например *errorText="a test"
, то он будет работать по назначению.
Проблема заключается в том, что исходный объект исключения выходит за пределы области видимости, когда возвращаемая нативная функция возвращается, и в этот момент текст становится недействительным, что означает, что это неверно, когда я пытаюсь маршалировать содержимое из указателя на него.
Одним из решений являются всегда сами бросать константные строки в виде исключения, как throw "something bad"
и поймать, что, поскольку эти постоянные строки остаются в силе, а затем поймать другие std::exception
сек возвращающихся только родовое строку ошибки, как «неопределенного станд :: исключение».
Это, очевидно, не идеально, хотя оно может работать. Вопрос в том, почему именно я не могу добраться до *what()
после выхода из функции. Хотя фактический объект исключения может выйти из области видимости, сообщение, которое оно было создано, обычно является константой. Если я сделаю бросок std::exception("something")
, тогда what
должен указывать на константу «что-то» и должен оставаться в силе после того, как исключение выходит за рамки.
Я рассмотрел вопрос о создании массива постоянных символов в dll и скопировал его() в него для последующего извлечения, но мне нужно поддерживать несколько одновременных доступов, которые могут иметь несколько исключений одновременно, над этим буфером.
Мне очень интересно, есть ли у кого-нибудь представление о том, почему what()
недоступен после того, как исключение оставляет видимость области или хорошая идея для решения этого более элегантно, чем путем исключения строковых исключений.
Редактировать: Еще одно решение состоит в том, чтобы выделить строку для управляемой стороны сообщения об ошибке и передать указатель на это для собственной стороны, чтобы вставить ошибку. Мне просто не нужно выделять новую строку для каждого вызова ... хотелось бы просто получить указатель на фактическое сообщение в том, что()
Возможно, релевантно. (http://stackoverflow.com/questions/150544/can-you-catch-a-native-exception-in-c-sharp-code) –
Возможно, решение: (http: // stackoverflow.com/questions/6850091/how-to-catch-unmanaged-c-exception-in-managed-c) –
Это, безусловно, похоже, но я не могу исключить исключение из моего собственного кода, как в ссылке. Это вызывает мгновенное завершение, и я также не могу выделить мусор, собранный для сообщения из собственного кода ... который является чистым C++ без добавления ms. Играй мне идею, тем не менее, поэтому я продлю свое сообщение – JoeTaicoon