繁体   English   中英

Java JNI“符号查找错误”与C ++库

[英]Java JNI “symbol lookup error” with c++ library

我正在树莓派上构建一个小应用程序。 我有一个JVM,它试图访问名为“ RCSwitch”的C ++库,我创建了JavaClass

public class NativeRCSwitchAdapter {

    private static final NativeRCSwitchAdapter instance = new NativeRCSwitchAdapter();

    public static NativeRCSwitchAdapter getInstance(){
        return instance;
    }
    private NativeRCSwitchAdapter(){};

    static{
        String path = NativeRCSwitchAdapter.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        System.load(path + "NativeRCSwitchAdapter.so");
}

    // methods to redirect to native layer (C++)
    public native void switchOn(String group, String channel);
    public native void switchOff(String group, String channel);
}

然后,我运行javac&javah以使Java为我生成头文件。

我创建了一个c ++文件:

#include "NativeRCSwitchAdapter.h"
#include "RCSwitch.h"
#include <stdio.h>
#include <iostream>

using namespace std;

JNIEXPORT void JNICALL Java_NativeRCSwitchAdapter_switchOn(JNIEnv * env, jobject obj, jstring jsGroup, jstring jsChannel ){
cout<<"teststring output"<<endl;
const char *csGroup = env->GetStringUTFChars(jsGroup, 0);
const char *csChannel = env->GetStringUTFChars(jsChannel, 0);

char sGroup[6];
char sChannel[6];

for (int i = 0; i<5; i++) {
    sGroup[i] = csGroup[i];
    sChannel[i] = csChannel[i];
}
sGroup[5] = '\0';
sChannel[5] = '\0';

cout<<"ONON"<<endl;
cout<<sGroup<<endl;
cout<<sChannel<<endl;


RCSwitch mySwitch = RCSwitch();

//for testing purposes set to the ELRO Power Plugs
mySwitch.setPulseLength(300);
mySwitch.enableTransmit(0);
mySwitch.setRepeatTransmit(3);

mySwitch.switchOn(sGroup, sChannel);
}

现在,此文件使用RCSwitch库,而该库又使用connectionPicture库。

现在,如果我编译,我运行此命令:

g++ -shared -I/usr/jdk1.8.0/include -I/usr/jdk1.8.0/include/linux NativeRCSwitchAdapter.cpp -o NativeRCSwitchAdapter.so

但是,如果从Java启动所有内容,我都会收到此错误:(简单的main,创建我的对象的实例,然后运行switchOn()

java: symbol lookup error: /home/pi/applications/Pi-jAutomation433/RCSwitchJNIWrapper/src/NativeRCSwitchAdapter.so: undefined symbol: _ZN8RCSwitchC1Ev

自从我上次用C编码以来,已经有时间了,所以请原谅我,但我相信这与编译器的链接阶段有关吗? 还是编译器会自动检查所有依赖项,然后自动检查其依赖项,直到没有其他依赖项,然后将它们很好地链接在一起并将其包装在应用程序中?

哦,如果有人在乎的话,这里是可以深入了解的仓库: Github仓库

感谢您的帮助!

更新

好的,所以我设法解决了这个错误。 事实证明(好吧,我已经知道了,但是)我对C ++编译器知识一无所知。 无论如何,我设法改变了错误。 我不知道我是否必须明确告诉g ++也包括RCSwitch.cpp。 好吧,现在我做到了。 下一个错误;-)我想这次应该很容易解决。 我得到一个未定义的符号“ pinMode”。 该符号是wireingPi库的一部分。 我是否必须包括在Java文件中执行的所有c库? 还是只有我访问的那个,之后对Java无关紧要?

您的本机函数声明被c ++编译器弄乱了。 在声明周围添加extern“ C”以解决问题。

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */
JNIEXPORT void JNICALL Java_NativeRCSwitchAdapter_switchOn(JNIEnv * env, jobject obj, jstring jsGroup, jstring jsChannel ){
#ifdef __cplusplus
}
#endif  /* __cplusplus */

编辑:您需要在创建共享库时包括所有其他对象/库。

请参阅此动态链接库问答。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM