如何使用JNA将结构数组的指针传递给java中的函数?

时间:2011-01-06 13:40:49

标签: java arrays pointers struct jna

我需要传递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 个答案:

答案 0 :(得分: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个字节(= 4个单元x每个MyStructure 12个字节)

这就是为什么当使用JNA和结构数组时你需要非常小心你所做的事情,因为结构数组与指向结构的指针数组非常不同