问题
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?!
回答1:
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.
回答2:
64-bit binaries cannot link to 32-bit ones or vice-versa. If you can't get the library you want in 32-bit, your best solution is to create a 32-bit proxy program that your main program controls. This is how Safari does Flash in 10.6 — the Flash plugin runs in its own address space.
回答3:
Just an FYI to anyone who stumbles across this, FMOD's development release contains a 64 bit dylib for Mac OS X. I'm using that now, and I'm sure it will be moved into the main line of the API soon.
来源:https://stackoverflow.com/questions/2412893/making-a-64-bit-shared-library-that-dynamically-links-to-a-32-bit-library-on-mac