JNAでC++から文字列を受け取る
JNAを用いてJavaからC++のライブラリの関数を使い、戻り値としてfloatとStringの配列を得たいのですが、floatは全く違う値になり、Stringは読み出そうとするとSIGSEGVが発生します。関数の呼び出しや、引数に与えた構造体がC++側で読めていることは確認しています。このサイトなどを参考に以下のようなコードを作成しています。どうすればエラーなく処理できるでしょうか?
c++
typedef struct result {
float* score;
char** value;
} result;
result myfunc(){
result *res = (result)malloc(sizeof(result));
memset(res, 0, sizeof(result));
(*res).score = (float*)malloc(sizeof(float) * 10);
memset((*res).score, 0, sizeof(float) * 10);
(*res).value = (char**)malloc(sizeof(char*) * 10);
for (size_t i = 0; i < 10; ++i) {
(*res).score[i] = getscore(i);
char* val = getvalue(i);
(*res).value[i] = (char *)malloc(sizeof(val));
memset((*res).value[i], 0, sizeof(val));
strcpy((*res).value[i], val);
}
/* ここでres.score[i], res.value[i]を出力すると正常な値になっているのを確認 */
}
java
import com.sun.jna.*;
import com.sun.jna.ptr.*;
public interface MyLib extends Library {
public static class result extends Structure {
public static class ByValue extends result implements Structure.ByValue {}
public Pointer value; // char**
public Pointer score; // float*
protected List getFieldOrder() {
return Arrays.asList(new String[]{
"value", "score",
});
}
}
MyLib INSTANCE = (MyLib) Native.loadLibrary("mylib", MyLib.class);
public result.ByValue myfunc();
}
public static void main(String[] args) {
MyLib.result.ByValue res = MyLib.INSTANCE.myfunc();
for(int i = 0; i < 10; i++){
float score = res.score.getFloat(i * Native.getNativeSize(Float.TYPE));
System.out.println(score); // 値が異なる
}
String[] strs = res.value.getStringArray(0, 10);// SIGSEGVが発生
for (String s: strs){
if(s != null){
System.out.println(s);
}
}
}