Update: After some more reading I see that this problem is totally general, you can’t mix architectures in the same process, so 64 bit Java cannot dlopen() a 32 bit library like FMOD. Is there any possible workaround for this, keeping in mind I’m writing my own C interface to the FMOD library?
I need to make a 64-bit dylib on Max OS X because Java Native Access only likes 64-bit libraries on 64-bit machines. The problem is, my C source code dynamically includes FMOD which on Mac only provides 32-bit dylibs. When I try to compile without the -m32 option (since I must output a 64-bit dylib) I get the following error:
gcc -dynamiclib -std=c99 -pedantic -Wall -O3 -fPIC -pthread -o ../bin/libpenntotalrecall_fmod.dylib ../../src/libpenntotalrecall_fmod.c -lfmodex -L../../lib/osx/
ld: warning: in /usr/lib/libfmodex.dylib, missing required architecture x86_64 in file
Undefined symbols:
"_FMOD_System_CreateSound", referenced from:
_startPlayback in ccJnlwrd.o
"_FMOD_Channel_GetPosition", referenced from:
_streamPosition in ccJnlwrd.o
"_FMOD_System_Create", referenced from:
_startPlayback in ccJnlwrd.o
"_FMOD_System_PlaySound", referenced from:
_startPlayback in ccJnlwrd.o
"_FMOD_Sound_Release", referenced from:
_stopPlayback in ccJnlwrd.o
"_FMOD_Channel_IsPlaying", referenced from:
_playbackInProgress in ccJnlwrd.o
"_FMOD_System_Update", referenced from:
_streamPosition in ccJnlwrd.o
_startPlayback in ccJnlwrd.o
"_FMOD_Channel_SetPaused", referenced from:
_startPlayback in ccJnlwrd.o
"_FMOD_System_Release", referenced from:
_stopPlayback in ccJnlwrd.o
"_FMOD_System_Init", referenced from:
_startPlayback in ccJnlwrd.o
"_FMOD_Channel_SetVolume", referenced from:
_startPlayback in ccJnlwrd.o
"_FMOD_System_Close", referenced from:
_stopPlayback in ccJnlwrd.o
"_FMOD_Channel_SetCallback", referenced from:
_startPlayback in ccJnlwrd.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [all] Error 1
Shouldn’t it be possible to get a 64 bit dylib from my source code that dynamically includes 32 bit libraries?!
As you’ve noted, you can’t mix architectures in the same process.
The workaround is then to have two processes. One of them is a 32 bit “helper” process that links to the 32-bit library and exposes its functions through some IPC mechanism, and the other is the 64-bit Java process linked to your own 64-bit library.
Your 64-bit library starts up the helper process, and provides a set of functions that it implements by passing requests to the helper process over the IPC mechanism and returning the results. The IPC can be as simple as a pair of anonymous pipes created with the
pipe()system call.