4

找到解决方案,留下帖子,以防有人发现它有用。

现在它看起来很健忘......但是当你在某个本机函数中通过它的指针传递结构时,它根本不知道它需要从本机内存中重新读取自己。
在像我这样的情况下,您需要做的就是在本机方法返回后调用结构方法 autoRead() ,结构将从本机内存中重新读取。


下面是一些例子:

// Original C code
typedef struct _SomeStructure {
  int x, y;
} SomeStructure;

void DoSomesthing(BYTE* data, int param);   //returns lots of data types, 
                                            //including SomeStructure    

// Equivalent JNA mapping
class SomeStructure extends Structure { public int x, y; }
void DoSomesthing(Pointer data, int param);
...
SomeStructure st = new SomeStructure();
DoSomesthing(st.getPointer(), 100);
st.autoRead(); //structure will be filled

仅当您需要从本机函数中获取某些结构时,此技巧才有效。

_ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _ __ _ __ _ __ _ _ ___

目前我正在研究 JNA 的扩展,所以它可以使用 MSCAPI,我遇到了一个小问题。

MSCAPI 函数以非常特定的方式设计,因此使用不同的参数以完全不同的方式工作。特别是

BOOL WINAPI CryptGetProvParam(
__in HCRYPTPROV hProv,
__in DWORD dwParam,
__out BYTE *pbData,
__inout DWORD *pdwDataLen,
__in DWORD dwFlags
);

当设置了 PROV_ENUMALGS 标志时,函数在 pbData 参数中返回PROV_ENUMALGS结构,但在其他情况下,它可以返回句柄、0t 字符串和许多其他内容。
所以我将其映射为:

boolean CryptGetProvParam(
HCRYPTPROV hProv,
int dwParam,
Pointer pbData,
IntByReference pdwDataLen,
int dwFlags
);

但是,当我m tried to call it with PROV_ENUMALGS.getPointer() (as pbData param) structure was not filling, so I ended up with having overloaded function with pdData type PROV_ENUMALGS. It工作时,但感觉有更好的方法可以做到这一点,然后有重载的功能,不会让我离开一个星期......

所以,各位,有什么建议吗?

PS对不起我的英语不好,以及格式化技巧。

也许我第一次不是很清楚,这里还有一些代码:
HCRYPTPROV hProv = JMSCAPIUtil.contextVerify(null, 420);

    PROV_ENUMALGS algs = new PROV_ENUMALGS();       

    if(Advapi32.INSTANCE.CryptGetProvParam(hProv,
            Advapi32.PP_ENUMALGS,
            algs,//.getPointer(),
            new IntByReference(algs.size()),
            Advapi32.CRYPT_FIRST)){
        System.out.println(algs.aiAlgid+"\t"+algs.dwBitLen+"\t"
                + new String(algs.szName,0,algs.dwNameLen.intValue()));
    }else{
        int err=Kernel32.INSTANCE.GetLastError();
        System.out.println(err);
    }       

    JMSCAPIUtil.contextRelease(hProv);  

这是结果:


26154 256 消费税 28147

显然,它调用

boolean CryptGetProvParam(
        HCRYPTPROV hProv,           
        int dwParam,                
        PROV_ENUMALGS pbData,           
        IntByReference pdwDataLen,  
        int dwFlags                         
        );

映射。

如果,//删除,它会调用

boolean CryptGetProvParam(
        HCRYPTPROV hProv,           
        int dwParam,                
        Pointer pbData,                 
        IntByReference pdwDataLen,  
        int dwFlags                     
        );

映射,结果将是:

0 0   

显然,当通过指针传递时,结构不会填充。

4

0 回答 0