0

IplImage ( )の配列のポインターをIplImage extends CvArray extends Structure implements cloneable関数に渡す必要がある C のネイティブ コードは次のとおりです。

cvCalcEigenObjects(
  nTrainFaces,
  (void*)faceImgArr,
  (void*)eigenVectArr,
  CV_EIGOBJ_NO_CALLBACK,
  0,
  0,
  &calcLimit,
  pAvgTrainImg,
  eigenValMat->data.fl);

私はこれを試しました:

cvCalcEigenObjects(
  nTrainFaces,
  faceImgArr[0].getPointer(),
  eigenVectArr[0].getPointer(),
  CV_EIGOBJ_NO_CALLBACK,
  0,
                null,
  calcLimit,
  pAvgTrainImg,
  eigenValMat.data.getFloatArray(0, Pointer.SIZE));

しかし、うまくいきませんでした。Java でのこの関数の宣言は次のようになります。

public static void cvCalcEigenObjects(int i, 
  Pointer pntr, 
  Pointer pntr1, 
  int i1, 
  int 2, 
  Pointer pntr2, 
  cxcore.CvTermCriteria ctc, 
  cxcore.IplImage ii, 
  FloatBuffer fb)
4

1 に答える 1

1

あなたの C プロトタイプは非常に不明確ですが、JNA では一見明らかではないが、それが問題の原因である可能性があることを紹介します。


構造体の配列を扱うときは、次のようなことをする必要があります:

// Syntax to get a new empty structure array (4 cells) to pass to a function
// which will populate it
MyStructureClass[] incomingStructArray = new MyStructureClass().toArray(4);

// Syntax to transform a standard java array to an array suitable 
// to be passed to a C function
MyStructureClass[] standardJavaStructArray = ....
MyStructureClass[] outgoingStructArray = new MyStructureClass().toArray(standardJavaStructArray);

なぜそうする必要があるのか​​ 疑問に思うなら(Javaの観点からは完全にクレイジーです)、Javaをコーディングしているのではなく、Cをコーディングしていることを覚えておく必要があります。

標準の Java 配列は実際には void* ですが、標準の C 配列は MyStructure* です。

MyStructure がメモリ内で 12 バイトを使用する場合:

  • MyStructureClass の 4 セル Java 配列は、メモリ内で 16 バイト (= 4 セル x ポインターあたり 4 バイト) を使用します (完全に正しいわけではありませんが、そう言っておきましょう。すべてのセルが != null の場合、追加の 48 バイトが MyStructureClass 自体に使用されます)。
  • MyStructure の 4 セル C 配列は 48 バイトを使用します (= MyStructure あたり 4 セル x 12 バイト)

そのため、構造体の配列は構造体へのポインターの配列とは大きく異なるため、JNA と構造体の配列を使用する場合は、何をするかに非常に注意する必要があります。

于 2011-01-21T14:59:19.087 に答える