9

I have a quick question about dealing with exceptions being thrown by libraries under JNA...

When I throw an exception in the underlying native code, JNA gets a invalid memory access error. I'm assuming this is because C libraries cannot throw an exception up through it's stack (it's actually C++/CLR but has C exports)? So is there no real way to report the exception to Java? Or "should it work" and I'm just doing something incredibly wrong?

DllExport void Initialize(char* dir)
{
    throw gcnew System::Exception("Testing");
}

It would be nice for Java to be able to detect these thrown exceptions, and I guess I could actually look into passing a memory pointer into all my C exports and check to see if those are null or not, but seems like a roundabout way.

StrangeWill
  • 2,106
  • 1
  • 23
  • 36

2 Answers2

7

C++ exceptions can only be handled in C++ code. They should never be allowed to escape the C++ world (i.e., a C interface of C++ code should never let exceptions propagate). It is not even safe to let a C++ exception propagate through a layer of C code between two C++ modules (e.g., when a C++ function calls a C function which in turn calls a C++ function).

One of the reasons for this is that there is no standard on how C++ exceptions should be implemented, so C++ modules are only binary-compatible if compiled by the same compiler (in the same version). So code in any other language can't be set up to handle C++ exceptions.

In this case (C++ library, C interface, called from Java) you would have to catch the C++ exception, propagate the information through the C interface (e.g., by using error return codes), check for it in Java and throw an exception there.

Philipp Wendler
  • 11,184
  • 7
  • 52
  • 87
  • 2
    I believe this is a better answer in practice, C++ errors should be handled on the C++ end and only passing the error code back to JVM via `Native.getLastError()` on the Java end. In JNI I found throwing a Java exception back to JVM is also debatable since throwing an exception doesn't end the C++ process. – Nicole Finnie Jun 10 '20 at 20:08
  • @Nicole Finnie ... like throwing an exception in a JNA callback? – Sam Ginrich Aug 01 '23 at 15:52
5

You need to handle the c++ exception yourself and instead build a java exception which can be passed to the java side of the code.

Roger Lindsjö
  • 11,330
  • 1
  • 42
  • 53
  • So I'd catch it on the C++/CLR side, and pass it back into java as multiple parameters? (Or in the instance of wanting simple error reporting, just having a second parameter, "char* err" would be enough). I thought I'd probably have to do that. – StrangeWill Aug 29 '11 at 17:59