SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构

Posted

技术标签:

【中文标题】SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构【英文标题】:SWIG Convert unsigned char* to 20 byte buffer Java structure 【发布时间】:2011-11-30 00:35:36 【问题描述】:

我有一个 C 函数(composeKey),它有一个输入 unsigned char* 参数(“key”)。在 C 端,“key”需要是一个空的 20 字节缓冲区结构。我假设一个大小为 20 的 Java 短数组将是传递 composeKey 的“key”参数的正确 Java 结构,但我不确定。也许我需要一个字节[20]。如果这是正确的,那么需要修改什么 SWIG 接口文件来生成带有 short[] 作为“key”参数输入的 composeKey Java 方法?

C Function:
int composeKey(const void* secret, int secret_len, unsigned char* key, int length);

【问题讨论】:

【参考方案1】:

解决您的具体问题

Java 在其类型系统中并没有真正区分 short[20] 和(例如)short[21]。不过,您可以非常简单地做一些非常明智的事情,让key 的长度对于 SWIG 来说总是 20 是显而易见的:

%module test

%include "arrays_java.i"

int func(unsigned char key[20]);

即使不直接更改函数的实际签名,这也可以工作 - SWIG 可以包装它,但让包装的代码调用一个仍然非常明智地采用 unsigned char* 的函数:

%module test

%
#include "header.h"
// fine even if it's func(unsigned char *key) in the header.
%

%include "arrays_java.i"
int func(unsigned char key[20]);

如果您从 Java 调用 func 并使用大小不合适的数组,您将收到由 SWIG 生成的代码自动为您抛出的 IndexOutOfBoundsException 异常。


一般解决方案

在这种特定情况下,"arrays_java.i" 已经提供了合适的类型映射。在更一般的情况下,这通过为 SWIG 提供 unsigned char [ANY] 的类型映射(字面意思是在 SWIG 类型映射语法中写成 ANY)来工作。然后将其实例化为特定值而不是 ANY(有点像 C++ 中的模板),然后您可以使用 $1_size 在您的类型图中访问 ANY 的特定值并提供填充大小的代码看起来(为简洁起见,省略了一些 JNI 细节)大致如下:

if (GetArrayLength(arg) != $1_size) 
    // Code to throw a Java Exception ...

然后在生成的包装器中变成:

if (GetArrayLength(arg) != 20) 
    // Code to throw a Java Exception ...

【讨论】:

以上是关于SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构的主要内容,如果未能解决你的问题,请参考以下文章

SWIG 将 const unsigned char example[] 包装到 Java byte[] 作为参数

TypeError:在方法“...”中,使用 swig 模块时类型为“unsigned char const *”的参数 1

Swig:将 std::vector<unsigned char> 传递给从 c++ 生成的 c# 函数

如何定义 swig 类型映射以将 unsigned char* 返回到 java

将 char* 转换为 unsigned char*

如何将 unsigned char[] 转换为 std::vector<unsigned char>