На вашем месте я бы пошел за исключением как можно скорее
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include "recipeNo019_ThrowException.h"
JNIEXPORT void JNICALL Java_recipeNo019_ThrowException_throwException
(JNIEnv * env, jobject obj) {
char exceptionBuffer[1024];
if(fopen("/this_will_fail", "r") == NULL) {
sprintf (exceptionBuffer, "%d:%s", errno, strerror(errno));
(*env)->ThrowNew (env,
(*env)->FindClass (env, "java/lang/Exception"),
exceptionBuffer);
}
}
, а затем в коде Java
я бы разложил код ошибки и сообщение об ошибке.
Затем внутри Java
вы можете легко получить доступ к errno
и message
.
public static native void throwException();
...
...
try {
throwException();
} catch(Exception ex) {
ex.getMessage();
}
Обновление
Обратите внимание, что при JNI
вовлекаясь в игру, все может усложниться (особенно с общими данными - errno
).
Вы можете представить себе один из сценариев ios - например:
public static class ErrnoGenerator implements Runnable {
boolean shouldIFail = false;
ThrowException exceptionGenerator = null;
public ErrnoGenerator(
ThrowException exceptionGenerator,
boolean shouldIFail) {
this.exceptionGenerator = exceptionGenerator;
this.shouldIFail = shouldIFail;
}
public void run() {
try {
if(shouldIFail) {
exceptionGenerator.throwException( shouldIFail );
Thread.sleep(1000);
System.out.println(
"true: expected == 2: "
+ exceptionGenerator.getErrno());
} else {
Thread.sleep(500);
exceptionGenerator.throwException( shouldIFail );
System.out.println(
"false: no expectations: "
+ exceptionGenerator.getErrno());
}
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) {
ThrowException thx = new ThrowException();
Thread t1 = new Thread(new ErrnoGenerator(thx, true));
Thread t2 = new Thread(new ErrnoGenerator(thx, false));
t1.start();
t2.start();
while(t1.isAlive() || t2.isAlive());
}
Однако даже без потоков на основе Java
, вызывающих JNI
, вы также можете ввести условие гонки
// This will set errno to "2"
thx.throwException( true );
try {
Path file = Paths.get("/tmp/path-to-file");
byte[] buf = "hello".getBytes();
Files.write(file, buf);
} catch(Exception ex) {
}
// it's gone - errno contains something completely
// different to what you have expected to be found
System.out.println(
"true: expected == 2: "
+ thx.getErrno());