我正在尝试将有效的 C JNI 绑定(bind)转换为 C++,因为我想从一些 Java 代码链接到 C++ 源代码(图像处理算法的开源实现)。我在 C 中获得了所有功能,这包括 Java 类、JNI 绑定(bind)的 C 版本和构建系统,不包括使用 C++ 源代码。
我现在正尝试将 JNI 绑定(bind)转换为 C++,以便我可以将 C++ 源代码添加到构建系统并从绑定(bind)中调用它,但我遇到了一个 undefined symbol 。
我的 Makefile 非常简单:
GCC = gcc -Wall -g -std=gnu99
CXX = g++ -Wall -g
LIBOBJS = parallelsurf_jni.o
LIB=libparallelsurf.so
DESTLIB=../../lib/$(LIB)
all: $(DESTLIB)
$(DESTLIB): $(LIB)
cp $(LIB) $(DESTLIB)
libparallelsurf.so: parallelsurf_ParallelSURF.h $(LIBOBJS)
ld --shared $(LIBOBJS) -o libparallelsurf.so
parallelsurf_ParallelSURF.h:
echo "Rebuilding JNI headers. Ensure java file has been recently built."
javah -classpath ../../parallelsurf.jar -jni parallelsurf.ParallelSURF
clean:
rm -f $(LIBOBJS) *~ parallelsurf_ParallelSURF.h $(LIB) $(DESTLIB) $(LIBOBJS)
JNI_INCLUDES = -I/usr/lib/jvm/java-6-sun/include/ -I/usr/lib/jvm/java-6-sun/include/linux -I/usr/lib/jvm/java-6-openjdk/include/
%.o: %.cpp
$(CXX) -shared -O2 -c -fPIC -fno-omit-frame-pointer -fno-stack-protector -D_REENTRANT $< $(JNI_INCLUDES)
因此,我的头文件是用 javah
自动生成的,从 .h
复制到 .cpp
时,我似乎没有损坏它>。根据 this post 的指导,.cpp 文件中没有 extern "C"
block .
我还按照这篇文章的指导包括了一个 pragma:Undefined Symbol _gxx_personality_v0 on link .编译指示是 #pragma GCC java_exceptions
现在,这个 undefined symbol (gxx_personality) 似乎在网络上得到了很好的引用/记录。许多帖子都指向关于 C++/Java exception handling 的评论,这表明使用该编译指示。但是,在包含该 pragma 之后,我得到了另一个没有很好覆盖的 undefined symbol (我得到了 1 个谷歌命中):_gcj_personality_v0
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/chardson/chardson/parallelsurf/lib/libparallelsurf.so: /home/chardson/chardson/parallelsurf/lib/libparallelsurf.so: undefined symbol: __gcj_personality_v0
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1675)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at parallelsurf.ParallelSURF.<clinit>(ParallelSURF.java:17)
at testpsurf.<init>(testpsurf.java:11)
at testpsurf.main(testpsurf.java:23)
我不确定如何处理这个 undefined symbol ,也不知道该转向哪里。也许我的 JNI 代码中有一个错误可以修复以解决这个问题?为了完整起见,我的 JNI C++ 代码包含在下面。
#include <jni.h>
#include <stdio.h>
#include <assert.h>
#pragma GCC java_exceptions
/*
* Class: parallelsurf_ParallelSURF
* Method: parallelsurf_get_keypoints
* Signature: (II[FZ)Ljava/util/ArrayList;
*/
JNIEXPORT jobject JNICALL Java_parallelsurf_ParallelSURF_parallelsurf_1get_1keypoints
(JNIEnv *jenv, jclass jcls, jint width, jint height, jfloatArray gray, jboolean rotInvariant)
{
// init arraylist class
jclass arrayListClass = jenv->FindClass("java/util/ArrayList");
assert(arrayListClass != NULL);
jmethodID alInitMethodId = jenv->GetMethodID(arrayListClass, "<init>", "()V");
assert(alInitMethodId != NULL);
jobject arrayList = jenv->NewObject(arrayListClass, alInitMethodId);
jmethodID alAddMethodId = jenv->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
assert(alAddMethodId != NULL);
// init keypoint class
jclass keypointClass = jenv->FindClass("parallelsurf/Keypoint");
assert(keypointClass != NULL);
jmethodID kpInitMethodId = jenv->GetMethodID(keypointClass, "<init>", "(DDDDID[D)V");
assert(kpInitMethodId != NULL);
jdoubleArray descriptor = jenv->NewDoubleArray(10);
assert(descriptor != NULL);
jdouble vals[10];
for (int i=0; i < 10; i++) {
vals[i] = (jdouble) i;
}
jenv->SetDoubleArrayRegion(descriptor, 0, 10, vals);
// create keypoint
jobject kp = jenv->NewObject(keypointClass, kpInitMethodId,
(jdouble) 1, (jdouble) 2, (jdouble) 3,
(jdouble) 4, (jint) 5, (jdouble) 6,
descriptor);
// add to arraylist
jenv->CallBooleanMethod(arrayList, alAddMethodId, kp);
jenv->DeleteLocalRef(kp);
return arrayList;
}
感谢观看。非常感谢您的帮助。
最佳答案
gcc-help 邮件列表上的一些好先生想出了这个:
- 代替
#pragma GCC java_exceptions
来处理__gxx_personality_v0,在-l gcc_s
中创建ld
链接 - 如果 __gcj_personality_v0 未定义,则在
-l gcj
中创建ld
链接 - 有
ld
链接-l stdc++
- 确保您的机器上有 libstdc++、libgcjX-dev(X 是一个版本)和 libgcc
如果您使用 g++ 链接(我没有),其中一些可能会自动发生(stdc++?)
此外,请确保您没有忘记(或丢失)JNI header 的 #import
行——您将需要 extern C {}
位,否则你会得到一个 UnsatisfiedLinkError
关于java - JNI 绑定(bind) - undefined symbol : gcj_personality_v0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5130921/