gpt4 book ai didi

带有 C++ 库的 Java JNI "symbol lookup error"

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:03:23 27 4
gpt4 key购买 nike

我正在树莓派上构建一个小应用程序。我有一个 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 库,而 RCSwitch 库又使用 wiringPi 库。

现在如果我编译我运行这个:

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 编写代码以来,已经过去了,所以请原谅我,但我相信它与编译器的链接阶段有关?还是编译器会自动检查所有依赖项,然后检查它们的依赖项,直到找不到更多依赖项,然后将它们很好地链接在一起并将其包装在应用程序中?

哦,如果有人关心的话,这是深入了解的 repo 协议(protocol): Github repo

感谢您对我的帮助!

更新

好吧,我设法解决了这个错误。事实证明(嗯,我有点知道,但是是的)当涉及到 C++ 编译器知识时,我是一个安静的傻瓜。无论如何,我设法改变了错误。我不知道我必须明确告诉 g++ 也包含 RCSwitch.cpp。好的,现在我做到了。下一个错误 ;-)我想这次应该很容易解决。我得到一个 undefined symbol “pinMode”。这个符号是 wiringPi 库的一部分。我是否必须包含在我的 java 文件中执行的所有 c 库?或者只有我访问的那个和之后的任何东西对 java 都无关紧要?

最佳答案

您的 native 函数声明正在被 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 */

编辑:您需要将所有其他对象/库包含到共享库的创建中。

查看此 Dynamic Link Library问答。

关于带有 C++ 库的 Java JNI "symbol lookup error",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19098323/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com