制作一个 64 位共享库,动态链接到 Mac OS X Snow Leopard 上的 32 位库
更新:经过更多阅读后,我发现这个问题是完全普遍的,你不能在同一个进程中混合架构,因此 64 位 Java 不能 dlopen()
像 FMOD 这样的 32 位库。是否有任何可能的解决方法,请记住我正在编写自己的 FMOD 库的 C 接口?
我需要在 Max OS X 上制作 64 位 dylib,因为 Java Native Access 只喜欢 64 64 位机器上的 64 位库。问题是,我的 C 源代码动态包含 FMOD,它在 Mac 上仅提供 32 位 dylib。当我尝试在不使用 -m32 选项的情况下进行编译时(因为我必须输出 64 位 dylib),我收到以下错误:
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
难道不能从动态包含 32 位库的源代码中获取 64 位 dylib 吗? !
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?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如您所指出的,您不能在同一流程中混合架构。
解决方法是有两个进程。其中一个是 32 位“帮助程序”进程,它链接到 32 位库并通过某种 IPC 机制公开其功能,另一个是链接到您自己的 64 位库的 64 位 Java 进程。
您的 64 位库启动帮助程序进程,并提供一组通过 IPC 机制将请求传递到帮助程序进程并返回结果来实现的函数。 IPC 可以像使用
pipe()
系统调用创建的一对匿名管道一样简单。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.64 位二进制文件无法链接到 32 位二进制文件,反之亦然。如果您无法获得所需的 32 位库,最好的解决方案是创建一个由主程序控制的 32 位代理程序。这就是 Safari 在 10.6 中处理 Flash 的方式 — Flash 插件在其自己的地址空间中运行。
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.
仅供任何偶然发现此问题的人参考,FMOD 的开发版本包含适用于 Mac OS X。我现在正在使用它,并且我确信它很快就会被移到 API 的主线中。
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.