带有 JNA 的 SDK Nikon C

问题描述 投票:0回答:1

我正在研究用 C 语言编写的 Nikon SDK 和带有 JNA 库的 Java 程序之间的包装。

所有进程都以 dll 内的 EntryPoint (MAIDEntryPoint) 结束。 这个EntryPoint在C中的签名是:

SLONG CallMAIDEntryPoint( 
    LPNkMAIDObject  pObject,    // module, source, item, or data object
    ULONG       ulCommand,  // Command, one of eNkMAIDCommand
    ULONG       ulParam,        // parameter for the command
    ULONG       ulDataType, // Data type, one of eNkMAIDDataType
    NKPARAM         data,           // Pointer or long integer
    LPNKFUNC    pfnComplete,    // Completion function, may be NULL
    NKREF       refComplete )   // Value passed to pfnComplete

我感兴趣的值是

NKPARAM data
,即下一个结构:

//stEnum Struct

typedef struct tagNkMAIDEnum
{
    ULONG       ulType;         // one of eNkMAIDArrayType
    ULONG       ulElements;     // total number of elements
    ULONG       ulValue;        // current index
    ULONG       ulDefault;      // default index
    SWORD       wPhysicalBytes;         // bytes per element
    LPVOID  pData;              // allocated by the client
} NkMAIDEnum, FAR* LPNkMAIDEnum;

EntryPoint 的范围是填充参数

LPVOID pData
pData
参数是一个以这种方式分配的指针:

NkMAIDEnum stEnum;
stEnum.pData = malloc(stEnum.ulElements * stEnum.wPhysicalBytes);

我所做的是“翻译”jna 结构和 EntryPoint,即:

//EntryPoint
int MAIDEntryPoint(NkMAIDObject pObject,
                   int kNkMAIDCommand_capGetArray,
                   int ulCapID,
                   int kNkMAIDDataType_enumPtr,
                   NkMAIDEnum nkMAIDEnum,
                   Object o,
                   int i);

Struct 将被定义为 Java 类:

@Structure.FieldOrder({"ulType", "ulElements", "ulValue", "ulDefault", "wPhysicalBytes", "pData"})
public class NkMAIDEnum extends Structure {
    public NativeLong ulType;
    public NativeLong ulElements;
    public NativeLong ulValue;
    public NativeLong ulDefault;
    public short wPhysicalBytes;
    public Pointer pData;
}

此时我将

Pointer pData
初始化为:

NkMAIDEnum nkMAIDEnum = new NkMAIDEnum ();
nkMAIDEnum.pData = new Memory(nkMAIDEnum.ulElements.longValue()*nkMAIDEnum.wPhysicalBytes);

nResult = INSTANCE.MAIDEntryPoint(
                   pRefMod.pObject,                
                   kNkMAIDCommand_CapGetArray,     
                   ulCapID,                        
                   kNkMAIDDataType_EnumPtr,        
                   nkMAIDEnum,                     
                   null,
                   0);

然后将其传递给 EntryPoint,但我收到一个 Invalid Access Memory 。 我认为问题是如何初始化Java-JNA部分中的pData或者NkMAIDEnum类中的pData应该是什么样的数据

例如,我不关心其他 EntryPoint 的参数,因为它们是正确的,并且参数

nkMAIDEnum.ulElements
nkMAIDEnum.wPhysicalBytes
都是不等于 0 或 null 的数字。

请帮助我理解我错在哪里,我被困住了

java c sdk java-native-interface jna
1个回答
0
投票

我看到三个可能的问题:

  1. JNA 需要足够的类型信息才能在结构(用于内存分配)或方法/函数签名(用于堆栈)中分配正确的字节数。

    您使用

    Object
    来映射
    MAIDEntryPoint()
    中的第六个参数肯定是错误的。 JNA 无法知道需要多少字节。由于该参数实际上是
    LPNKFUNC pfnComplete
    ,因此看起来
    Pointer
    是它的正确映射。

  2. 另一种可能性是,如果您错误地映射(或分配)了作为

    NkMAIDObject
    第一个参数的
    MAIDEntryPoint()
    类型。您还没有向我们展示映射,但这很可能是一个不正确的分配。

  3. 最后,您指示本机分配已通过

     malloc(stEnum.ulElements * stEnum.wPhysicalBytes)
    和状态

    完成

参数

nkMAIDEnum.ulElements
nkMAIDEnum.wPhysicalBytes
是不等于0或空的数字。

  • 但是,您不会显示这些分配的位置。您只需使用
    new NkMAIDEnum()
    定义一个新结构,并且不为
    .ulElements
    .wPhysicalBytes
    分配任何值,因此它们实际上被初始化为零。 (除非您有代码,否则您不会向我们展示。)
© www.soinside.com 2019 - 2024. All rights reserved.