我有一个名为 libmylibrary.a 的文件和一个名为 mylibrary.h 的头文件 这包含一个名为 myfunction() 的函数。我将它们与 cpp 文件(HelloWorldJNI.cpp)组合起来,创建了一个名为 native.dll 的新库。但是,当我尝试使用 JNI 在 Java 中编译 native.dll 时,我无法找到 libmylibrary.a 和 mylibrary.h 中的函数。
mylibrary.h
// mylibrary.h
#ifndef MYLIBRARY_H
#define MYLIBRARY_H
#ifdef __cplusplus
extern "C" {
#endif
void myFunction(); // Declare the function prototype
#ifdef __cplusplus
}
#endif
#endif // MYLIBRARY_H
这些是我遵循的步骤
1.创建用于集成JNI的java文件(HelloWorldJNI.java)
public class HelloWorldJNI {
static {
System.load("/home/centos/test5/native.dll");
}
public static void main(String[] args) {
new HelloWorldJNI().sayHello();
}
//native method with no body
public native void sayHello();
}
2.使用此命令创建了 HelloWorldJNI.h 文件
javac -h . HelloWorldJNI.java
3.将 mylibrary.h 文件和 HelloWorldJNI.h 文件与我的 cpp 文件(HelloWorldJNI.cpp)集成
#include<iostream>
#include<jni.h>
#include "mylibrary.h"
#include "HelloWorldJNI.h"
void sayHello(){
myFunction();
}
int main() {
sayHello(); // Call the function from the library
return 0;
}
JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHello
(JNIEnv* env, jobject thisObject) {
sayHello();
}
4.编译这些文件(创建.o文件)
g++ HelloWorldJNI.cpp -L. -lmylibrary -I"/home/centos/jdk-21.0.1/include" -I"/home/centos/jdk-21.0.1/include/linux" -o HelloWorldJNI.o
5.生成.o文件到.dll文件
g++ -shared -o native.dll HelloWorldJNI.o
6.编译并运行HelloWorldJNI.java
java HelloWorldJNI
出现此错误:
java: symbol lookup error: /home/centos/test5/native.dll: undefined symbol: myFunction
如何将 libmylibrary.a 合并到我的 Java 代码编译中以确保它识别 libmylibrary.a 中的函数?
PS:我确信 libmylibrary.a 没有问题,因为我能够使用纯 c++ 调用 myFunction() 但在使用 JNI 时似乎存在某种我无法弄清楚的链接问题
我尝试了您的所有步骤并进行了一些细微的更改,这对我有用。附上构建脚本:
JAVA_SDK_HOME=/home/user/lib/jdk-21.0.1
g++ -fPIC -c mylibrary.cpp -o mylibrary.o
ar rs mylibrary.a mylibrary.o
$JAVA_SDK_HOME/bin/javac -h . HelloWorldJNI.java
g++ -fPIC -shared -o native.dll HelloWorldJNI.cpp mylibrary.a \
-I $JAVA_SDK_HOME/include/ \
-I $JAVA_SDK_HOME/include/linux
不过有一些注意事项:
JNIEXPORT
实际上是 __declspec(dllexport)
,而不是 __declspec(dllimport)
*.so
文件,您需要使用 -fPIC