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

发布于 2024-12-18 16:34:20 字数 358 浏览 1 评论 0原文

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

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

I have a C function (composeKey) that has an input unsigned char* parameter ("key"). On the C side, "key" needs to be an empty 20 byte buffer structure. I'm assuming that a Java short array with a size of 20 would be the correct Java structure to pass composeKey's "key" parameter, but I'm unsure. Maybe a byte[20] is what i need. If that is correct, what SWIG Interface file modification is needed to generate the composeKey Java method with a short[] as input for the "key" parameter?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

高冷爸爸 2024-12-25 16:34:20

针对您的具体问题的解决方案

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++ 中的模板),然后您可以使用 在类型映射中访问 ANY 的特定值>$1_size 并提供填充尺寸的代码(为简洁起见,省略了一些 JNI 详细信息),大致如下:

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

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

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

Solution to your specific problem

Java doesn't really distinguish between short[20] and (e.g.) short[21] in its type system. You can do something that's pretty sensible quite simply though, by making the fact that the length of key is always 20 obvious to SWIG:

%module test

%include "arrays_java.i"

int func(unsigned char key[20]);

This can work even without changing the actual signature of your function directly - SWIG can wrap that, but have the wrapped code call a function that still takes unsigned char* quite sensibly:

%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]);

If you call func from Java with an inappropriately sized array you'll get an IndexOutOfBoundsException exception thrown for you automatically by the code that SWIG generates.


General solution

In this specific case "arrays_java.i" provides a suitable typemap already. In the more general case this works by providing SWIG with a typemap for unsigned char [ANY] (literally write ANY in SWIG typemap syntax). This then gets instantiated for specific values in place of ANY (sort of like a template in C++), you can then access the specific value of ANY in your typemap using $1_size and supply code that the sizes gets filled in to look (some JNI details omitted for brevity) roughly like:

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

Which then in the generated wrapper becomes:

if (GetArrayLength(arg) != 20) {
    // Code to throw a Java Exception ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文