c # — заставить функцию extern C ++ возвращать сообщение, если выброшено исключение

Я хотел бы, чтобы моя внешняя функция C ++ возвращала сообщение при возникновении исключения. Что-то вроде этого:

extern "C" __declspec(dllexport) const char* __stdcall Calculate(double &result, double a, double b)
{
try
{
result = InternalCalculation(a, b);
}
catch(std::invalid_argument& e)
{
return e.what();
}
return "";
}double InternalCalculation(double a, double b)
{
if(a < b)
{
const char* err = "parameters error!";
throw std::invalid_argument(err);
}
return sqrt(a - b);
}

С другой стороны, я вызываю функцию из моей программы на C # и хотел бы показать ошибку в MessageBox:

[DllImport(@"MyDll.dll", EntryPoint = "Calculate")]
private static extern IntPtr Calculate(out double result, double a, double b);

private void Calculate()
{
IntPtr err;
double result = 0;
err = Calculate(out result, out 2, out 3);
var sErr = Marshal.PtrToStringAnsi(err);
if (string.IsNullOrEmpty(sErr))
MessageBox.Show(sErr);
...
}

К сожалению, это не работает .. MessageBox просто показывает случайные символы.

Я удивлен, потому что если я заменю:

return e.what();

от:

const char* err = "parameters error!";
return err;

Тогда «ошибка параметров!» будет отображаться правильно в окне сообщения кода C #. И то и другое err а также e.what() одного типа (const char*), так что не так с e.what()??

3

Решение

Ваша функция возвращает BOOL вместо этого, со строкой сообщения об ошибке в качестве параметра, например:

BOOL Calculate(double &result, double a, double b, char *pMsg, size_t nMsgSize)
{   try
{   result = InternalCalculation(a, b);
}
catch(std::invalid_argument& e)
{   strncpy_s(pMsg, nMsgSize, e.what(), _TRUNCATE);
return FALSE;
}
return TRUE;
}

и вызвать его как

StringBuilder sErr = new StringBuilder(256);
if (!Calculate(out result, 2, 3, sErr, 256))
MessageBox.Show(sErr);
1

Другие решения

Когда вы используете строковый литерал в качестве возвращаемого значения из функции, он будет работать правильно. Но то же самое не относится к локальной переменной e. Вам нужно создать динамический char* хранить ценность e.what() в этом и вернуть это значение.

2

Это потому, что строка исключения указывает на строку, которая уничтожается, как только обработчик исключения завершен. Вам может потребоваться вернуть, например, std::string и маршал это в C # string,

0
По вопросам рекламы [email protected]