0

我正在使用 MinGW(不是 Cygwin)并尝试获取一些已成功移植到 Mac 以在 Windows 上运行的 OSS 代码。所需的最终构建是可用作 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 的等效项)的显式命令行调用的任何建议,这些建议将使这些函数能够编译和链接。

语气

4

1 回答 1

2

你不想让你的功能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");
}

}
于 2012-05-21T18:37:47.460 回答