Yeah, another pair of eyes would be good. I’ll sort-out that project observer thing, but in the interim, here’s the changes:
The generated C++ alGetProcAddress() method, plus that printf() statement:
/* Java->C glue code:
* Java package: net.java.games.joal.impl.ALImpl
* Java method: java.nio.ByteBuffer dispatch_alGetProcAddress(java.lang.String fname)
* C function: ALproc alGetProcAddress(const ALchar * fname);
*/
JNIEXPORT jobject JNICALL
Java_net_java_games_joal_impl_ALImpl_dispatch_1alGetProcAddress0__Ljava_lang_String_2J(JNIEnv *env, jobject _unused, jstring fname, jlong procAddress) {
LPALGETPROCADDRESS ptr_alGetProcAddress;
const char* _UTF8fname = NULL;
ALproc _res;
ptr_alGetProcAddress = (LPALGETPROCADDRESS) (intptr_t) procAddress;
assert(ptr_alGetProcAddress != NULL);
if (fname != NULL) {
_UTF8fname = (*env)->GetStringUTFChars(env, fname, (jboolean*)NULL);
if (_UTF8fname == NULL) {
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"),
"Failed to get UTF-8 chars for argument \"fname\" in native dispatcher for \"dispatch_alGetProcAddress\"");
return 0;
}
}
_res = (* ptr_alGetProcAddress) ((ALchar *) _UTF8fname);
printf("C++ - alGetProcAddress = 0x%p\n", _res);
if (fname != NULL) {
(*env)->ReleaseStringUTFChars(env, fname, _UTF8fname);
}
if (_res == NULL) return NULL;
return (*env)->NewDirectByteBuffer(env, _res, sizeof(ALproc));
}
New method in net.java.games.joal.impl.ALProcAddressLookup, called from my test case after an OpenAL context had been made current. Tries to set the address values in the ALProcAddressTable class using AL.alGetProcAddress()
public static void repopALProcAddrTable() {
String addrOfPrefix = "_addressof_";
AL al = ALFactory.getAL();
System.out.println("\nLooking-up EFX function pointers");
for (Field field: ALProcAddressTable.class.getFields()) {
// Skip non-address fields
String fieldname = field.getName();
if (!fieldname.startsWith(addrOfPrefix)) {
continue;
}
try {
String functionname = fieldname.substring(addrOfPrefix.length());
long fieldval = field.getLong(alTable);
// Skip fields which have already been valued
if (fieldval != 0) {
continue;
}
// Get the address
ByteBuffer procAddress = al.alGetProcAddress(functionname);
long procAddressVal = 0;
if (procAddress.limit() == 8) {
procAddressVal = procAddress.getLong();
}
else {
procAddressVal = procAddress.getInt();
if (procAddressVal < 0) {
procAddressVal -= 0xffffffff00000000L;
}
}
System.out.println("Java - Address of " + functionname + ": 0x" + Long.toHexString(procAddressVal) + "\n");
field.setLong(alTable, procAddressVal);
}
catch (Exception ex) {
throw new RuntimeException("Unable to repopulate ALProcAddressTable values");
}
}
}