• 締切済み

C++のDLLをJAVAで実行→うまく行かない。。

Java素人です。ちょっと教えてほしいです。 以下のC++は問題なく動作します。 //C++ヘッダの記述 VC_Header_API int _stdcall GET_DATA(UINT32* abcData, int* Count); //C++の記述 UINT32* abcData; abcData= (UINT32*)malloc(128 * 512 * 1024 * sizeof(UINT32)); int Count= 0; return= GET_DATA(abcData, &Count); //→ 正しい値が取れる。適当な数字の羅列データ しかしJavaでは、結果の戻り値が取れなくて。。。 //Javaの記述 (中略です) //C++ Function name int SET_DATA(int setData, byte[] Err); int GET_DATA(int[] abcData, int[] Count); byte[] Err = new byte[128]; int[] abcData= new int[100000]; int[] Count= new int[1000]; return = abcDLL.INSTANCE.GET_DATA(5555, Err); //→問題なく動作します。Errの文字コードも取れます。 return = abcDLL.INSTANCE.GET_DATA(abcData, Count); //→これを実行したとき、abcデータとCountがすべて”0”... 正しい値が入ってこないのは、abcData, Countの渡し方の問題だと思われるんですが。。。 他の関数は問題なく動作可能です。 問題ない渡し方、分かりますでしょうか?アドバイスいただきたいです。 よろしくお願いいたします。

  • Java
  • 回答数2
  • ありがとう数0

みんなの回答

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.2

回答No.1の者です。 C++の関数をJavaから呼ぶにはJava Native Interface(JNI)という機能を使うのが古くからの方法でした。 https://ja.wikipedia.org/wiki/Java_Native_Interface 質問文にある情報だけではJNIを使っていないように見えますが、GET_DATA()メソッドの定義の中で使っているかもしれません。 最近のバージョンのJavaだとJNIとは別のやり方があります。 abcDLLやabcDLL.INSTANCEの型(クラス)は何なのか、その定義はどうなっているのかを知る必要があります。 念のための確認ですが、もしC++で書かれた関数のDLLファイルを削除した状態で問題のJavaプログラムを実行したらどのような結果になりますか。 DLLファイルが見つからないとUnsatisfiedLinkErrorが発生するはずです。

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.1

質問文にある情報だけでは答えるのは困難です。abcDLL.INSTANCE.GET_DATA()がどのように定義されているのかが一番の鍵だと思います。 >return = abcDLL.INSTANCE.GET_DATA(5555, Err); //→問題なく動作します。Errの文字コードも取れます。 Errの型はbyte[]で、intとbyte[]を引数に取るのはGET_DATA()ではなくSET_DATA()です。単純な書き間違いだろうと思いますが。 「Errの文字コードも取れます」というのも、質問文内に関係する情報が書かれていないので回答者にとっては残念ながら意味不明です。

関連するQ&A

  • Javaのプログラムの質問です。

    Javaのプログラムについての質問です。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。  注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中に番号を振ってあります。 import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.List; class LocalList implements List{  private int Count;  private String Data[];  private Iterator ite;  private ListIterator lite;  // コンストラクタ  void mylist(){   Data = new String[10];   Count = 0;  }  (1)  public boolean add(Object str){   if(Count >= 10){    return false;   }   Data[Count ++] = new String((String)str);   return true;  }  public void add(int i,Object str){  }        public boolean addAll(Collection c){   return false;  }        public boolean addAll(int i,Collection c){   return false;  }    (2)  public void clear(){   Count = 0;  }  public boolean contains(Object str){   return false;  }          public boolean containsAll(Collection c){   return false;  }  public boolean equals(Object str){   return false;  }    (3)  public Object get(int i){   return (i >= Count);  }  public int hashCode(){   return -1;  }  public int indexOf(Object str){   return -1;  }  public boolean isEmpty(){   return false;  }  public Iterator iterator(){   return ite;  }     public int lastIndexOf(Object str){   return -1;  }     public ListIterator listIterator(){   return lite;  }     public ListIterator listIterator(int i){   return lite;  }    (4)  public Object remove(int i){   return (i >= Count);  }    public boolean remove(Object str){   return true;  }         public boolean removeAll(Collection c){   return false;  }         public boolean retainAll(Collection c){   return false;  }    (5)  public Object set(int i,Object str){   return Data[i];  }    (6)  public int size(){   return Count;  }  public List subList(int i,int j){   return this;  }  public Object[] toArray(){   return Data;  }  public Object[] toArray(Object[] a){   return Data;  } } class Main {  public static void main(String[] args) {   mylist sub = new mylist();   sub.add("ビルドバーニングガンダム");   sub.add("ライトニングガンダム");   sub.add("ウイニングガンダム");   sub.add("ガンダムフェニーチェリナーシタ");   sub.add("R・ギャギャ");   for(int i = 0; i < sub.size(); i++){      System.out.println(sub.get(i));   }   // 改行   System.out.println();   // setメソッド   sub.set(1,"ガンダムエピオン");   for(int i = 0; i < sub.size(); i++){    System.out.println(sub.get(i));   }   // 改行   System.out.println();   // sizeメソッド   System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n");   // removeメソッド   sub.remove(1);   for(int i = 0; i < sub.size(); i++){       System.out.println(sub.get(i));   }   // clearメソッド   sub.clear();   System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです");    } } setメソッドとremoveメソッド以外は起動するのようになったのですが、この2つがうんともすんとも動きません。ジェネリクス型を使うという考え方もあるらしいのですが、ネットで調べてもピンと来ず寸詰まり状態になってしまっています。後少しだと思うのですが。。。。 どなたかご教授頂けないでしょうか?よろしくお願い致します。

  • Java クラスを使ったソート

    Javaで隣接交換法を用いて配列dataを昇順に並び替え、出力するプログラムを作成する。 ただし、ループ処理には、int型の変数は使わず、以下のCounterクラスを使用する。 という課題が出て、とり組んでみたのですが所々よく分からないので、お力添えしていただければと思います。 課題には下記のような条件が書いてありました。 配列data={54,76,32,89,45,11,8,54,29,67}; [クラス] Counter [インスタンス変数] int型の値を保持するcount [コンストラクタ] 引数で渡された値を初期値としてインスタンス変数に設定する。 引数を省略された場合、ゼロを設定する。 [メソッド] increment 値に1加算する decrement 値に1減算する compareTo 以下の処理を行う Counterの保持している値が引数に指定された値と 等しい場合、値0を返す。 Counterの保持している値が引数に指定された値より 小さい場合、0より小さい値を返す。 Counterの保持している値が引数に指定された値より 大きい場合、0より大きい値を返す。 get Counterの保持している値を添え字として、 引数で渡された配列の要素を取得します。 set Counterの保持している値を添え字として、 第1引数で渡された配列に第2引数で渡された値を設定します。 以下組んだものです。 ---- class Counter { int count = 0; Counter(int count) { this.count = count; } Counter() { this.count = 0; } public int get(int[] data) { return this.count; } public void set(int[] data, int count) { this.count = count; } public void increment() { this.count = count + 1; } public void decrement() { this.count = count - 1; } public int compareTo() { return count; } } public class Lesson09 { public static void main(String args[]) { Counter counter = new Counter(0); int[] data = {54, 76, 32, 89, 45, 11, 8, 54, 67}; counter.get(data); counter.set(data, 0); } } ---- とりあえず、compareToとsetとgetの部分をどう記述していいのかがよく分かりません。 よろしくお願いします。

    • ベストアンサー
    • Java
  • javaのプログラミングについての質問です。

    Javaのプログラムについての質問です。長くなってしまいますがご容赦下さい。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。以下が現在までに作成したコードになります。 注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中にコメントを振ってあります。 import java.util.List; import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; class Mylist implements List{   private int Count;   private String Data[];   // コンストラクタ   public Mylist(){    Data = new String[10];    Count = 0;   } /** 実装するaddメソッド @return boolean APIの設定に従う @param e エレメント(要素) **/   public boolean add(E e){    Data[Count] = (String)e;   Count++;   return true;   }   public void add(int i,Object str){   }   public boolean addAll(Collection c){     return false;   }   public boolean addAll(int i,Collection c){     return false;   } /** 実装するclearメソッド **/   public void clear(){     Count = 0;   }   public boolean contains(Object str){     return false;   }   public boolean containsAll(Collection c){     return false;   }   public boolean equals(Object str){     return false;   } /** 実装するgetメソッド @return E エレメント(要素) @param i 指定されたインデックス番号 **/   public E get(int i){      /*     エレメントeに、String型Data[i]を     キャストして格納*/     E e = (E)Data[i];     return e;   }   public int hashCode(){     return -1;   }   public int indexOf(Object str){     return -1;   }   public boolean isEmpty(){     return false;   }   public Iterator iterator(){     return null;   }   public int lastIndexOf(Object str){     return -1;   }   public ListIterator listIterator(){     return null;   }   public ListIterator listIterator(int i){     return null;   }    /**   * 実装するremoveメソッド   * @return E エレメント(要素)   * @param index 指定されたインデックス番号   **/   public E remove(int index){ /* Dataを最大まで回し、iをインクリメントしたData[i++]を String型Dataに格納する*/ for(int i = index; i < Data.length; i++){ Data[i] = Data[index++]; } Count--; E e = (E)Data; return e; } public boolean remove(Object str){ return false; } public boolean removeAll(Collection c){ return false; } public boolean retainAll(Collection c){ return false; } /** * 実装するsetメソッド * @return E エレメント(要素) * @param i 指定されたインデックス番号 * @param element 置き換える要素 **/ public E set(int i,E element){ // String型Dataにelementをキャストして格納 Data[i] = (String)element; // エレメントeにData[i]をキャストして格納 E e = (E)Data[i]; // 値を返す return e; } /** * 実装するsizeメソッド * @return int 指定されたインデックス番号 **/ public int size(){ return Count; } public List subList(int i,int j){ return this; } public Object[] toArray(){ return Data; } public Object[] toArray(Object[] a){ return Data; } } class Main { /** メインメソッド **/ public static void main(String args[]) { Mylist sub = new Mylist(); /* addメソッドを実装し、機体名を要素とする。 addを最大まで回し、getメソッドで要素を取り出して表示する*/ sub.add("ビルドバーニングガンダム"); sub.add("ライトニングガンダム"); sub.add("ウイニングガンダム"); sub.add("ガンダムフェニーチェリナーシタ"); sub.add("R・ギャギャ"); sub.add("ユニコーンガンダム"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // sizeメソッド System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n"); // setメソッド sub.set(0,"ガンダムエピオン"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // 改行 System.out.println(); // removeメソッド sub.remove(1); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // clearメソッド sub.clear(); System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです"); } } コンパイルして実行すると、removeメソッドで指定した箇所ではなく、要素の1番最後が削除されています。思うに、removeメソッドを実装する所のfor(int i = index; i < Data.length; i++){の中の条件が違うと思うのですが。。。。 また、現在addには10個箱を作成するようにしていますが、11個目をメインクラス内で用意した場合、例外ではなく新たに箱を作らなければならない、という後だしジャンケン的な事を言われて、思わず「じゃあArrayListでいいじゃないか」と思ってしまいました。 気を取り直してこの3連休で終わらせたいと思っています。ここまでで現状コードの完成は50%かそれ以下だとは思いますが、どなたか上記2点について御教授頂けないでしょうか。よろしくお願い致します。

  • C#からVC++DLLの呼び出しに失敗する

    VS.NET2005のC#からVC++6.0で作成したDLLを呼び出しています。 VCのデバッガでデバッグしてみると呼び出した関数は正常に動作しているようなのですが、最後のreturnを実行しC#に戻るところでエラーが出てしまいます。 C#側では「'System.ExecutionEngineException' のハンドルされていない例外が ConsoleApplication1.exe で発生しました。」となります。 C#での宣言は、 [DllImport("test.dll")] public static extern uint TestFunc(ref byte[] moji, ref uint nagasa); です。 VC++の宣言は、 __declspec(dllexport) unsigned long __stdcall TestFunc(unsigned char* moji, unsigned long* nagasa) です。 C#へ値を返さない関数は問題ないのですが、値を返そうとすると起きるようです。不備などあればご指摘いただけないでしょうか。 ちなみにVB6からは問題なく動作できました。

  • C#からDLLの呼び出し方

    visual studio 2008 express edition C#3.5 を使用しています。 http://www.hata.cc/docs/wlinee/1.html を参考にC++からではMySub関数を呼び出すことができたのですが、 C#から呼び出そうと次のように記述したのですが、 [System.Runtime.InteropServices.DllImport("a.dll")] extern int WINAPI MySub(int a, int b); 書き終わったときに、MySubの下に赤線がでて「;が必要です」 というエラーが出てしまいます・・・ たぶん「WINAPI」が認識されてないと思うのですが、 どのように記述すればよいのでしょうか? ~C++での記述~ [dllcall.cpp] #include "stdafx.h" #include <windows.h> #include <conio.h>  // getch( ) を使用するのに必要 extern int WINAPI MySub(int a, int b); int _tmain(int argc, _TCHAR* argv[]) { int c; c=MySub(9, 3); printf("ans=%d\n",c); getch();// キーが押されるまで待つ return 0; } [a.cpp] __declspec(dllexport)int WINAPI MySub(int a, int b) { return a-b; }

  • javaのカウントアップについて

    javaのEclipseを使っています。 カウントアップ後、表示する度に、 1, 2, 3, …と表示するプログラムを作りたいです。 プログラム例を教えて下さい。 public class Test { public static void main(String[] args) { Count count = new Count(); int scount = count.read(); count.write(scount); } } class Count { int count = 1; int read() { return count++; } void write(int scount) { System.out.println(scount); } }

  • C++ シングルトン マルチスレッド

    標準C++でシングルトンを実装したいのですが。 class Singleton{ public: static Singleton* getInstance(){ if (_instance == NULL){ //スレッドAがこの時点で、スレッドBがNULLチェックすると破綻する _instance = new Singleton(); } return _instance; } private: Singleton(); static Singleton* _instance; }; マルチスレッドになると上記のパターンで破綻するといわれどうしたものかと考えております。 static Singleton* _instance = new Singleton(); と出来れば解決なのですが 「static const int データメンバ以外をクラス内で初期化することはできません」 とのことでそれもできず。 どのようにすればよいでしょうか。

  • java setterとgetterについて

    データをセットしたファイルとは別のファイルからゲットしたいの ですが、できるのでしょうか? できるのでしたら、方法を教えてください。 具体的には下記のような感じです。 (かなり端折っている&あまり理解できていないので  おかしいsrcかもしれませんが、  やりたいことは、A.javaでセットした値をB.javaでゲットしたい  のです・・・。) 宜しくお願いいたします。 ■Data.java public class Data{   private String mojiData;   public Data(String _mojiData){     mojiData = _mojiData;   }   public void setMojiData(String _mojidata){     mojiData = _mojiData;   }   public void getMojiData(){     return mojiData;   } } ■A.java public class A extend JApplet{   public void init(){     Data[] data = new Data[2];     param[0] = a;     param[1] = i;     for(int i=0; i<2; i++){       data[i] = new Data("");       data[i].setMojiData(param);     }   } } ■B.java public class B extend JApplet{   String strData = new String[2];   public void ren(){     Data[] data;     for(int i=0; i<2; i++){       String strData[i] = data[i].getMojiData();     }   } }

    • ベストアンサー
    • Java
  • C#についてです

    複数のグラフを作成しようと思い、2つのクラスを作りました。 1つ目のクラスで、下のように書き、 public class clsWave { public const int count = 1024; public int[] data = new int[count];     public byte range; public double[] realValue = new double[count]; public PictureBox pcb;     public Pen myPen; ; public void Draw(Graphics g, int v) { int h = pcb.Height; int w = pcb.Width; int stpW = w / count; // X座標       Point[] lp = new Point[count]; for (int i = 0; i < data.Length; i++) { lp[i] = new Point(i * stpW, h - (int)(realValue[i] / (v * 8) * h)); } g.DrawLines(myPen, lp); } } もう一つのクラスで、グラフを下のように作りました。      clsWave BI = new clsWave(); clsWave BV = new clsWave(); clsWave CI = new clsWave(); clsWave CV = new clsWave(); clsWave EI = new clsWave(); clsWave EV = new clsWave(); clsWave SI = new clsWave(); clsWave SV = new clsWave(); この、グラフを配列にしたいのですが、私の力では、まだわかりません。 どのように作ればよいのでしょうか?教えてください。よろしくお願いいたします。

  • JAVAでCの関数ポインタのようなことをするには?

    CのプログラムをJAVAに移植しています。関数ポインタのプログラムを移植したいのですがやり方がよく判りません。interfaceを実装するとできるようですが・・・ 以下のCプログラムをJAVAに移植する方法を教えてください。 #include <stdio.h> int func(int , int); int main() { int (*po)(int , int) , i; po = func; i = (*po)(10 , 3); printf("%d" , i); return 0; } int func(int i , int j) { return i + j; }

    • ベストアンサー
    • Java

専門家に質問してみよう