在Windows上使用GCC编译DLL时出现问题

在Windows上使用GCC编译DLL时出现问题,windows,gcc,dll,java-native-interface,Windows,Gcc,Dll,Java Native Interface,我正在使用MinGW(而不是Cygwin),并试图获得一些已成功移植到Mac上的OSS代码,以便在Windows上运行。理想的最终版本是一个.DLL,可用作JNI库(这是Mac上的.jnilib),但我在编译最后一个包装接口的.cpp文件时遇到了问题 问题是my.cpp文件中的每个函数在编译时都会生成以下形式的错误: g++ -I/various/such/entries -D_inline=__inline -I/c/java/include -I/c/java/include/win32 -

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

问题是my.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");
}
然而,虽然这解决了编译问题,但它只让我在链接方面遇到了一个问题,这个问题可能是ifdef权宜之计的结果,也可能不是ifdef权宜之计的结果(很可能只与损坏有关):每个基于C的基础函数都丢失了,即使它们在Mac构建中从-L指定的静态库中可靠地找到,如图所示的FOO_int2str:

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'
我有点不知所措。我通过谷歌找到的少数东西中,大多数都与其他构建环境(例如cygwin和微软提供的编译器)有着相当紧密的上下文联系。我有gcc和MinGW,希望避免回答与dlltool或Cygwin相关的问题,因为我正在使用的代码已经通过了很多人的手,并且其中包含了黑暗魔法(如语音识别),就像笼中的闪电一样。。。我改变的越多,我运行mac平台上现有功能消失的风险就越大

我是makefile写作的新手。目前我拥有这座大楼是一个令人高兴的意外,因为代码是从一个千兆字节的大型语料库中提取出来的,具有非常沉重的构建格式塔,目标是移动平台而不是桌面平台;我知道我必须转储一个构建上下文,并且我已经成功地完成了(至少对于Mac而言)。再也回不去了

提前感谢您对g++(或类似gcc的等效程序)的显式命令行调用提供的任何建议,这些建议将使这些函数得以编译和链接


音调

你不想让你的函数成为静态的,因为这给了它们内部链接。错误消息告诉您,这与正在导出的函数不兼容。您的JNI函数需要有外部链接。这可以通过将
静态
替换为
外部
来实现。但是,由于外部链接是函数的默认值,您只需删除
静态
链接说明符并省略
extern

您还需要指定C链接,因为您正在编译为C++而不是C。如果使用默认的C++链接,那么最终会出现C++名称的篡改,这是链接错误的原因。 因此,您的代码应该如下所示:

#include <jni.h> 

extern "C"
{

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

}
#包括
外部“C”
{
JNIEXPORT void JNICALL Java\u com\u me\u包\u类名\u Moo
(JNIEnv*env,jclass clazz)
{
printf(“Moo!\n”);
}
}

David,谢谢你的帮助。隐马尔可夫模型。。。这并不意味着一行回复。我在整个事件中添加了外部“C{}(保留我的“#define static”),这在Mac上编译时是不需要的,但仍然得到对com_me_package_ClassName.o:com_me_package_ClassName.cpp:(.text+0x84):对`\u imp_FOO_rc2str'的未定义引用“我需要看得不那么深一点。我看到我的linking命令没有显示任何要链接的库。我需要解决这个问题。谢谢你的帮助,所以上面的farPost是错误的。。。-L和-L参数就在那里。我看到缺少imp_uu前缀的符号在没有前缀的.a文件中。我不知道如何告诉ld停止思考前缀-Wl,--启用自动导入和-Wl,--禁用自动导入似乎没有帮助OOPS忘记标记有帮助的第一响应者@david heffernan。如果我的附加信息有帮助,请提前感谢。我想知道问题是否在于我的C函数FOO_rc2str编译错误?托尼:我想也许我需要给你贴上标签,@DavidHeffernan,而不是作为编辑的一部分。这是希望。
#include <jni.h> 

extern "C"
{

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

}