在另一个文件中链接/使用.so文件

时间:2014-11-29 23:05:30

标签: java c++ java-native-interface

我有以下getmacip.cpp文件,其中包含以下snipp代码

// ...code

#include "test.h"

// ...code   

Test obj;
obj.printDem();

// ...code

这是test.h文件

#ifndef TEST_H
#define TEST_H
class Test
{
    public:
        void printDem();  
};
#endif

这是test.cpp文件

#include <iostream>
using namespace std;

void printDem()
{
    cout << "deus.ex.machina." << endl;
}

我通过jni一起使用java和c ++。我已经得到文件getmacip.cpp与java一起工作,正如你所看到的,我试图从getmacip.cpp文件中调用printDem()方法。我首先用以下内容编译getmacip.cpp:

g++ -fPIC -o libgetmacip.so -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux getmacip.cpp -lc

这很好用。但是,当我对test.cpp执行相同操作并运行程序时,我会收到错误

/usr/lib/jvm/java-8-oracle/bin/java: symbol lookup error: /home/karl/workspace/sslarp/lib/libgetmacip.so: undefined symbol: _ZN4Test8printDemEv

我显然错误地链接了文件!

2 个答案:

答案 0 :(得分:2)

printDem()的定义不属于班级Test

使用

#include <iostream>
#include "test.h"
using namespace std;

void Test::printDem() {
    cout << "deus.ex.machina." << endl;
}

此外,您应该link方法definition进入共享库,如下所示:

g++ -fPIC -o libgetmacip.so \
    -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux \
        detmacip.cpp test.cpp

另外我应该提一下,原始JNI是一个普通的C接口,所有本机调用都是作为C函数声明声明的函数(他们的实现可以使用C ++,check this tutorial。此外还有SWIG项目有助于为C ++自动创建所需的包装器{g,t}。

答案 1 :(得分:1)

您可以查看此处的符号类型

$ nm -D libgetmacip.so

将生成符号列表

如果必须解码C ++名称,请使用c ++ filt

$ nm -D libgetmacip.so | C ++ FILT

检查“man nm”以获取有关如何标记/使用符号的信息