Как передать указатель на массив структуры для функции в Java с использованием JNA? - PullRequest
0 голосов
/ 06 января 2011

Мне нужно передать указатель массива 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)

1 Ответ

1 голос
/ 21 января 2011

Ваш прототип 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 на самом деле является недействительным *, но стандартный массив C - это MyStructure *

Если MyStructure использует 12 байт в памяти:

  • Java-массив из 4 ячеек MyStructureClass использует 16 байтов (= 4 ячейки x 4 байта на указатель) в памяти (не совсем верно, но, скажем так; если все ячейки! = Ноль, то для 48 будут использоваться дополнительные 48 байтов). MyStructureClass сами)
  • 4-ячеечный массив MyStructure C использует 48 байт (= 4 ячейки x 12 байт на MyStructure)

Вот почему при использовании JNA и массива структур вам нужно быть очень осторожным с тем, что вы делаете, потому что массив структур сильно отличается от массива указателей на структуру

...