On Friday, 2 December 2016 at 08:13:51 UTC, Jacob Carlborg wrote:
On 2016-12-01 02:58, Timothee Cour via Digitalmars-d-learn wrote:
eg:

```
dlib.d:
extern(C) void dfun(){assert(0, "some_msg");}

clib.cpp:
extern "C" void dfun();
void fun(){
  try{
    dfun();
  }
  catch(...){
    // works but how do i get "some_msg" thrown from D?
  }
}
```

At least for a C++ exception it's possible to get the current exception with __cxxabiv1::__cxa_current_primary_exception(). I verified and it works for C++ exceptions. I would think that the following works for D exceptions, but I cannot even catch the D exception in C++. Maybe it's not working properly on macOS.

// c++
void foo();
const char* getExceptionMessage(void*);

void bar()
{
    try
    {
        foo();
    }
    catch(...)
    {
        void* e = __cxxabiv1::__cxa_current_primary_exception();
        if (e)
        {
            const char* msg = getExceptionMessage(e);
            if (msg)
                printf("%s\n", msg);
            else
                printf("no message\n");
        }
        else
        {
            printf("no exception\n");
        }
    }
}

// d

extern(C++) void foo()
{
    throw new Exception("foo");
}

extern(C++) immutable(char)* getExceptionMessage(void* e)
{
    if (e)
    {
        auto t = cast(Throwable) e;
        return t.msg.ptr;
    }

    return null;
}

I'm compiling the C++ code with clang++ and I need to link with libc++abi.

Exceptions thrown from D set a different exception class in the header, and the C++ personality routine (i.e the function that gets called for each catch block) only handles exceptions which displays the C++ exception class, so let D exceptions slip through.

To catch exceptions thrown by D code in C++ I think this would have to be done by throwing a C++ exception (eventually wrapping a D class), but this is yet to be implemented.

Reply via email to