MinGW 的编译器选项 Wl,--kill-at 不起作用

Posted

技术标签:

【中文标题】MinGW 的编译器选项 Wl,--kill-at 不起作用【英文标题】:MinGW's compiler option Wl,--kill-at does not work 【发布时间】:2011-01-31 11:39:42 【问题描述】:

我目前正在努力使用 Eclipse CDT 和 MinGW 编译一个供 JNI 使用的 Dll。

按照教程,我创建了一个声明本地方法的 Java 类,然后使用 javah 获取相关的头文件并在 C++ 类中实现它。

C++ 代码非常简单并且可以编译,但是当我将库加载到 Java 类中时,我得到了这个错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Main.integerMethod(I)I
    at Main.integerMethod(Native Method)
    at Main.main(Main.java:12)

我“探索”了dll,发现应该调用的方法都有一个像“@14”这样的后缀。问题是,我已经在使用 -Wl,--kill-at 编译器选项,它应该删除这些非常令人尴尬的标签......那为什么它不起作用呢?

编译日志如下:

**** Rebuild of configuration DLL for project JniCTest ****

**** Internal Builder is used for build               ****
g++ -IC:\Program Files\Java\jdk1.6.0_13\include -IC:\Program Files\Java\jdk1.6.0_13\include\win32 -O3 -Wall -c -fmessage-length=0 -mno-cygwin -D__int64=long long -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -oMain.o ..\Main.cpp
g++ -o libJniCTest.dll -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -shared -olibJniCTest.dll Main.o
Build complete for project JniCTest
Time consumed: 375  ms.  

编译器选项有问题吗?感谢您的帮助。

【问题讨论】:

【参考方案1】:

找到解决方案。 --kill-at 选项没有放在正确的命令中。事实上,MinGW 首先将文件编译成一个 .o 目标文件,然后(第二行)它从这个 .o 文件进行链接。因此该选项必须放在第二行。

更正了源文件 Main.cpp 和输出 DLL libJniCTest.dll 的命令:

g++ -I"C:\Program Files\Java\jdk1.6.0_13\include" -I"C:\Program Files\Java\jdk1.6.0_13\include\win32" -O0 -Wall -c -oMain.o ..\Main.cpp
g++ -Wl,--kill-at -shared -olibJniCTest.dll Main.o

【讨论】:

【参考方案2】:

另外,不要忘记像这样包装你的实现

extern "C" 

//implemented methods


我花了好几个小时才弄明白

【讨论】:

感谢@Jonah 的精确性,欢迎来到 Stack Overflow :) 不过有一点。如果您想说的内容更多的是评论而不是问题的具体答案,则应将其写在评论而不是答案中。【参考方案3】:

我遵循这个简单的 JNI tutorial 在 IBM 网站上 并在 Windows XP 上使用以下命令编译给定的 Sample1.c 文件。它对我来说工作正常。

gcc -Wall -Wl,--kill-at -shared Sample1.c -o Sample1.dll -I"C:\Program Files\Java\jdk1.7.0\include" -I"C:\Program Files\Java\jdk1.7.0\include\win32"

P.S:根据你的系统更改 JDK 路径。

【讨论】:

以上是关于MinGW 的编译器选项 Wl,--kill-at 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Cena使用

gcc编译器选项-Wl,--no-undefined(告诉链接器在链接过程中不允许有未定义的符号)(gcc编译器和链接器是分离的工具,它们需要通过选项来进行通信)

GCC选项_-Wl,-soname

GCC选项_-Wl,-soname

-Wl,-rpath=

使用 MinGW 编译 - 无法识别的命令行选项