JNI新手,写了个demo试试看,于是就core了。。代码如下
Java部分:
package SDK;
//此处各种import
public class Wrap {
private static Wrap instance = null;
private Wrap() {};
public synchronized static Wrap getInstance() {
if (instance == null) instance = new Wrap();
return instance;
}
public native void init(String log, int size);
//...
staitc { System.loadLibrary("wrap"); }
}
public class Demo {
private Wrap wrap;
public Demo(Wrap w) { this.wrap = w; }
public static void main(String[] args) {
Wrap wrap = Wrap.getInstance();
wrap.init(...);
....
}
}
native部分:
//include 如下头文件
//stdio.h stdarg.h stdlib.h string.h unistd.h sys/time.h
//pthread.h semaphore.h
//string list map
//BDSpeechSDK.hpp bds_ASRDefines.hpp bds_asr_key_definitions.hpp -- 第三方
//SDK_Wrap.h -- javac + javah生成的JNI头文件
class Log {
private
FILE* m_file;
public:
Log(): m_file(nullptr) {}
}
class Log log;
JNIEXPORT ... //此处省略
int main() {
return *(int*)(&log);
}
编译执行过程如下:
javac ...
javah ...
g++ -o libwrap.so -fPIC -shared ./main.cpp -I.... -Wall -O0 -fPIC -g -D__LINUX__ -Wno-unknown-progmas -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++11 ... -lrt -ldl -lpthread (省略部分分别是一堆头文件包含路径和一堆静态库 .a 文件)
g++ -o main ./main.cpp -I.... -Wall -O0 -fPIC -g -D__LINUX__ -Wno-unknown-progmas -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++11 ... -lrt -ldl -lpthread (省略部分同上)
mv libwrap.so $JAVA_RUN_PATH
java -Djava.library.path=`pwd` SDK.Demo
native部分如果编译为libwrap.so,那么java启动时会core dump,观察dump日志说C++中的log初始化挂在了 m_file(nullptr) ,引起了SigSEGV
可native部分如果编译为bin,直接linux下执行这个bin的话,并没有什么问题。
泪奔了。。求助啊~有什么排查思路不。。。