I'm trying to catch and wrap a custom c++ exception in c#.
Let's say I have the following exception c++ custom exception:
//custom_exception.h
namespace ns
{
namespace exception
{
class CustomException
{
public:
CustomException(const char* msg, EStatus status) :
m_status(status)
{
strcpy(m_msg, msg);
}
const char* what() const { return m_msg; }
EStatus status() const { return m_status; };
private:
EStatus m_status;
const size_t m_max_len = 100;
char m_msg[100];
};
}
}
I've created the following interface file custom_exception.i according to the SWIG doc (16.3.4 Custom C# ApplicationException example):
/************************/
/***** Main Module ******/
/************************/
%module custom_exception
%{
#include "custom_exception.h"
%}
%insert(runtime) %{
// Code to handle throwing of C# CustomApplicationException from C/C++ code.
// The equivalent delegate to the callback, CSharpExceptionCallback_t, is CustomExceptionDelegate
// and the equivalent customExceptionCallback instance is customDelegate
typedef void (SWIGSTDCALL* CSharpExceptionCallback_t)(const char *, int);
CSharpExceptionCallback_t customExceptionCallback = NULL;
extern "C" SWIGEXPORT
void SWIGSTDCALL CustomExceptionRegisterCallback(CSharpExceptionCallback_t customCallback) {
customExceptionCallback = customCallback;
}
// Note that SWIG detects any method calls named starting with
// SWIG_CSharpSetPendingException for warning 845
static void SWIG_CSharpSetPendingExceptionCustom(const char *msg, int status) {
customExceptionCallback(msg, status);
}
%}
%pragma(csharp) imclasscode=%{
class CustomExceptionHelper {
// C# delegate for the C/C++ customExceptionCallback
public delegate void CustomExceptionDelegate(string message, int status);
static CustomExceptionDelegate customDelegate =
new CustomExceptionDelegate(SetPendingCustomException);
[global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="CustomExceptionRegisterCallback")]
public static extern
void CustomExceptionRegisterCallback(CustomExceptionDelegate customCallback);
static void SetPendingCustomException(string message, int status) {
SWIGPendingException.Set(new CustomException(message, status));
}
static CustomExceptionHelper() {
CustomExceptionRegisterCallback(customDelegate);
}
}
static CustomExceptionHelper exceptionHelper = new CustomExceptionHelper();
%}
%pragma(csharp) moduleclassmodifiers=%{
// Custom C# Exception
public class CustomException: global::System.ApplicationException {
public CustomException(string message, int status)
: base(message) {
m_status = status;
}
private int m_status;
public int status
{
get => m_status;
set => m_status = value;
}
}
public class%}
%typemap(throws, canthrow=1) ns::exception::CustomException{
SWIG_CSharpSetPendingExceptionCustom($1.what(), (int)($1.status()));
return $null;
}
/************************/
/** Include Files ***/
/************************/
%include "custom_exception.h"
Swig creates the exception .cs class, but unfortunately, I wasn't able to catch it via a csharp code.
I get the following message:
Unhandled exception. System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
Can someone please point me to the right direction ( didn't find anything relevant on google)?