Я хотел бы, чтобы моя внешняя функция 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()
??
Ваша функция возвращает 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);
Когда вы используете строковый литерал в качестве возвращаемого значения из функции, он будет работать правильно. Но то же самое не относится к локальной переменной e. Вам нужно создать динамический char*
хранить ценность e.what()
в этом и вернуть это значение.
Это потому, что строка исключения указывает на строку, которая уничтожается, как только обработчик исключения завершен. Вам может потребоваться вернуть, например, std::string
и маршал это в C # string
,