ラズベリーパイで小さなアプリを構築しています。「RCSwitch」と呼ばれる C++ ライブラリにアクセスしようとする JVM があります 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からすべてを開始すると、このエラーが発生します:(単純なメイン、オブジェクトのインスタンスを作成し、switchOn()を実行します
java: symbol lookup error: /home/pi/applications/Pi-jAutomation433/RCSwitchJNIWrapper/src/NativeRCSwitchAdapter.so: undefined symbol: _ZN8RCSwitchC1Ev
最後にCでコーディングしてから時間が経ちましたので、ご容赦ください。コンパイラのリンク段階と関係があると思いますか? それとも、コンパイラはすべての依存関係を自動的にチェックし、それ以上の依存関係が見つからなくなるまで依存関係をチェックし、それをすべてうまくリンクしてアプリにラップしますか?
ああ、誰かが気にかけているなら、ここにレポがあります: Github repo
助けてくれてありがとう!
アップデート
さて、私はこのエラーを取り除くことができました。結局のところ、私はC++コンパイラの知識に関しては無口です。とにかく、エラーを変更することができました。RCSwitch.cpp も含めるように g++ に明示的に指示する必要があることを知りませんでした。さて、そうしました。次のエラー ;-) 今回はかなり簡単に対処できるはずです。未定義のシンボル「pinMode」が表示されます。このシンボルは、wiringPi ライブラリの一部です。Java ファイルで実行されるすべての c ライブラリを含める必要がありますか? または、私がアクセスしたものだけで、その後はJavaにとって重要ではありませんか?