在Windows上使用GCC编译DLL的问题

时间:2012-05-21 18:24:03

标签: windows gcc dll java-native-interface

我正在使用MinGW(不是Cygwin)并尝试获取一些我已成功移植到Mac上的OSS代码以在Windows上运行。所需的最终版本是一个可用作JNI库的.DLL(这是Mac上的.jnilib),但我在编译包装界面的最后一个.cpp文件时遇到了问题。

问题是我的.cpp文件中的每个函数在编译时都会以下列形式生成错误:

g++ -I/various/such/entries -D_inline=__inline -I/c/java/include -I/c/java/include/win32 -c -o com_me_package_ClassName.o com_me_package_ClassName.cpp
com_me_package_ClassName.cpp:84:31: error: external linkage required for symbol 'void Java_com_me_package_ClassName_Moo(JNIEnv*, jclass)' because of 'dllexport' attribute
// ditto the above for every such function

让我们看看上面显示错误的一个函数:

#include <jni.h> // of course this is in here
static JNIEXPORT void JNICALL Java_com_me_package_ClassName_Moo
    (JNIEnv *env, jclass clazz) {
printf("Moo!\n");
}

经过一些谷歌搜索,我看到其他人有一个项目,其中“静态”功能是一个问题,所以我尝试在创建错误的任何函数之前将以下hack添加到.cpp文件:

#ifdef WIN32
#define static 
#endif

然而,虽然这解决了编译问题,但它只会让我遇到链接问题,这可能是也可能不是ifdef权宜之计的结果(并且可能只与修改有关):每个基于C的即使在-L指定的静态库(例如FOO_int2str)中的Mac构建中可靠地找到它们,基础函数也会丢失,如下所示:

g++ -D_inline=__inline -shared -o /output/lib/libfoo_jni.dll   com_me_package_ClassName.o -L/some/number/of/such/things -lz -lzipfile
com_me_package_ClassName.o:com_me_package_ClassName.cpp:(.text+0x84) : undefined reference to `_imp__FOO_int2str'

我有点失落。我通过Google找到的少数几件事与其他构建环境(例如cygwin和Microsoft提供的编译器)有着相当大的内容联系。我有gcc和MinGW,并希望避免与dlltool或Cygwin这样的问题相关的答案,因为我正在处理的代码已经通过很多手并且内部有黑暗的魔法(例如语音识别),就像笼状闪电一样。 ..我越多,我运行的风险就越大,mac平台上现有的功能就会消失。

我是makefile写作的新手。我现在拥有这座建筑物是一件令人高兴的事故,因为代码是从一个巨大的语料库中提取出来的,其中包含一个非常重的构建格式,目标是移动而不是桌面平台;我知道我必须转储的构建上下文,我已经成功完成了(至少对于Mac)。那里没有回头路了!

提前感谢任何对g ++(或类似gcc的等价物)进行显式命令行调用的建议,这些建议将使这些函数进行编译和链接。

1 个答案:

答案 0 :(得分:1)

你不想让你的函数static,因为它给了他们内部的联系。正如错误消息告诉您的那样,这与导出的函数不兼容。您的JNI功能需要具有外部链接。这可以通过将static替换为extern来实现。但是,由于外部链接是函数的默认设置,因此您只需删除static链接说明符并省略extern

您还需要指定C链接,因为您要编译为C ++而不是C.使用extern "C"执行此操作。如果您使用默认的C ++链接,那么您最终会得到C ++名称修改,我怀疑这是链接器错误的原因。

所以你的代码应该是这样的:

#include <jni.h> 

extern "C"
{

JNIEXPORT void JNICALL Java_com_me_package_ClassName_Moo
    (JNIEnv *env, jclass clazz) 
{
    printf("Moo!\n");
}

}