Java 指向JNA中作为参数的结构指针的指针

Java 指向JNA中作为参数的结构指针的指针,java,c,pointers,jna,Java,C,Pointers,Jna,第三方DLL有一个函数,该函数需要指向结构的指针作为参数: __declspec(dllimport) int __stdcall SegmentImages( unsigned char* imageData, int imageWidth, int imageHeight, int* numOfFinger, SlapInfo** slapInfo, const char* outFilename ); 它将手指指纹的“拍击”图像(通常为4个)分割为单个指纹(

第三方DLL有一个函数,该函数需要指向结构的指针作为参数:

__declspec(dllimport) int __stdcall
SegmentImages( unsigned char* imageData, int imageWidth, int imageHeight,
               int* numOfFinger, SlapInfo** slapInfo, const char* outFilename );
它将手指指纹的“拍击”图像(通常为4个)分割为单个指纹(outFilename+手指数)

SlapInfo的定义是:

struct SlapInfo {
    int fingerType; 
    Point fingerPosition[4];
    int imageQuality;
    int rotation;
    int reserved[3];
};

struct Point {
    int x;
    int y;
};
C语言中的示例片段:

unsigned char* imageData;
int imageWidth, imageHeight;
//obtain imageData, imageWidth and imageHeight from scanner...
int numOfFinger;
SlapInfo* slapInfo;

int result = SegmentImages( imageData, imageWidth, imageHeight, &numOfFinger,
                            &slapInfo, FINGER_IMG_PATH);
JNA 根据,在我的情况下,我应该使用“Structure.ByReference[]”:

因此,我在Java/JNA中映射如下:

结构 用法 但是使用这种方法,我得到了一个错误:

java.lang.Error: Invalid memory access
        at com.sun.jna.Native.invokeInt(Native Method)
        at com.sun.jna.Function.invoke(Function.java:419)
        at com.sun.jna.Function.invoke(Function.java:354)
        at com.sun.jna.Library$Handler.invoke(Library.java:244)
        at com.sun.proxy.$Proxy0.SegmentImages(Unknown Source)
        at scanners.JNAScanner.segmentToFile(JNAScanner.java:366)
我还尝试了:

  • PointerByReference而不是SlapInfo.ByReference[](如中所述)
  • “指针”类,如中所述
  • SlapInfo[](仅用于尝试)
在所有情况下,我都得到了错误“无效内存访问”


我做错了什么?

如果
SegmentImages
slapInfo
中返回一个或多个结构的地址,则需要使用
指针引用。实际的本机类型是
struct**
,但是在
slapInfo
中返回的值是指针

IntegerByReference iref = new IntegerByReference();
PointerByReference pref = new PointerByReference();
int result = SegmentImages(..., iref, pref, ...);
如果在单个块中返回结构,则可以执行以下操作:

SlapInfo s = new SlapInfo(pref.getValue());
SlapInfo[] slaps = s.toArray(iref.getValue());

注意C函数声明中的
\uu stdcall
——您的库没有使用cdecl调用约定。您的库接口是否扩展了StdCallLibrary
?嗯,我正在尝试复制无效的内存访问,但无法复制。您确定已分配足够大的
slapInfoArray
?但同样,C示例只分配了一个指针,这表明函数可能正在用它自己分配的数组替换指针。如果不访问该库或其文档,几乎不可能猜测出可能出现的错误。是的,它扩展了StdCallLibrary,是的,如C示例所示,本机代码分配内存(还有另一个函数要释放内存)。尝试在C中创建一个函数原型,然后将其移植到Java。是一个指针结构工作示例,如果您的代码与此示例相同,并且不工作,那么您的结构可能存在特定问题
//imageData, width and height are with valid values
IntByReference nrOfFingers = new IntByReference();
SlapInfo.ByReference[] slapInfoArray = (SlapInfo.ByReference[]) 
                new SlapInfo.ByReference().toArray(4);
                //Usually, there are 4 fingers in a slap, but the correct
                //value should be the returned in nrOfFingers

int result = lib.SegmentImages(imageData, width, height,
                nrOfFingers, slapInfoArray, FINGER_IMG_PATH);
java.lang.Error: Invalid memory access
        at com.sun.jna.Native.invokeInt(Native Method)
        at com.sun.jna.Function.invoke(Function.java:419)
        at com.sun.jna.Function.invoke(Function.java:354)
        at com.sun.jna.Library$Handler.invoke(Library.java:244)
        at com.sun.proxy.$Proxy0.SegmentImages(Unknown Source)
        at scanners.JNAScanner.segmentToFile(JNAScanner.java:366)
IntegerByReference iref = new IntegerByReference();
PointerByReference pref = new PointerByReference();
int result = SegmentImages(..., iref, pref, ...);
SlapInfo s = new SlapInfo(pref.getValue());
SlapInfo[] slaps = s.toArray(iref.getValue());