SWIG 类型映射 uint8_t* 从 C/C++ 到 java.nio.ByteBuffer

2024-05-27

我正在尝试将输入和输出缓冲区从 C++ 传递给 java 类。 出于效率原因,我需要使用 ByteBuffer。

这两个缓冲区都是在 C++ 部分中分配的,我需要将它们传递给一个 java 函数,该函数将使用输入缓冲区进行一些计算并将结果写入输出缓冲区。

下面是 C++ 的一个简化示例:

// SWIG mapped with %feature("director") JavaDelegate;
class JavaDelegate {
public:
    JavaDelegate() {}
    virtual ~JavaDelegate() {}
    virtual int compute(const uint8_t* input, size_t inSize,
                        uint8_t* output, size_t maxOutSize,
                        int someFlag) = 0;
};

// assume inputBuf is filled with valid data
std::vector<uint8_t> inputBuf;
std::vector<uint8_t> outputBuf(10000);

// delegate also points to a valid SWIG mapped class
JavaDelegate* delegate;

void computeOutput() {
   int someFlag = 1;
   int numValuesComputed = delegate->compute(inputBuf.data(), inputBuf.size(), 
                                             outputBuf.data(), outputBuf.size(), 
                                             someFlag);
   std::cout << "Computed " << numValuesComputed << " value from input.\n";
}

在Java方面,我想实现这个(JavaDelegate类已由 SWIG 生成):

public class Delegate extends JavaDelegate {

    public long compute(java.nio.ByteBuffer input, 
                        java.nio.ByteBuffer output, 
                        long someFlag) 
    {
        // read input
        // compute something n values from m input values
        // write result to output
        return numOutputValues;
    }
}

问题是,我根本不知道如何进行类型映射以将普通 char* 包装到 ByteBuffer,特别是与为抽象基类打开的 SWIG 控制器功能结合使用。 我知道如何将 ByteBuffer 从 Java 传递到 C++,但我不知道如何执行相反的操作。

任何帮助表示赞赏!


前言:这不是 SWIG-ish 解决方案,这是通用目的,我发现this https://qinjin.wordpress.com/2011/10/11/mapping-between-char-and-byte-in-swig/与你的问题有些相关


首先,没有ref据我所知,Java 中的参数因此直接从 C++ 传递它不是一个选项,除非您准备好更改签名并将其作为返回值。这可以通过从 Java 传递 typewrapper 并让 C++ 在其中创建/设置缓冲区来规避,例如:

public class BufferWrapper {
    private ByteBuffer mBuffer;

    public void setBuffer(ByteBuffer buffer) {
        mBuffer = buffer;
    }
} 

只需将其传递给 C++ 并让它分配缓冲区并将其设置为包装器即可。

There's 新直接字节缓冲区 https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBufferJNI 函数完全满足您的需要:

分配并返回一个直接引用的 java.nio.ByteBuffer 从内存地址开始并扩展的内存块 容量字节。

调用此函数并返回结果的本机代码 字节缓冲区对象到Java级代码应该确保缓冲区 指的是可读取的有效内存区域, 如果合适的话,写作。尝试访问无效内存 Java 代码中的位置要么返回任意值,要么返回任意值 可见的效果,或导致抛出未指定的异常。


P.S 我们本可以采取其他方式 - ByteBuffer 已经wrap https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#wrap(byte%5B%5D)方法允许您包装现有的缓冲区byte[]这不完全是char*但我们可以嫁给他们(看看这个answer https://stackoverflow.com/questions/17124712/jni-android-converting-char-to-byte-array-and-return-it-to-java()).

深入了解 Jni 方法实现:

 jsize n = sizeof(yourBuf);
 jbyteArray arr = (*env)->NewByteArray(env, n);
 (*env)->SetByteArrayRegion(env,arr,0,n, (jbyte*)yourBuf);

However请注意,根据doc https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html这个函数会产生copy不只是包装,所以我注定它在这里没有多大帮助

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SWIG 类型映射 uint8_t* 从 C/C++ 到 java.nio.ByteBuffer 的相关文章

随机推荐

  • 用发电机创建一个背包

    我想创建一个dask Bag or dask Array 来自生成器列表 问题是生成器 评估时 对于内存来说太大了 delayed array delayed generator for generator in list of gener
  • 如何检查 Java 中的间隔列表 (Joda-Time) 是否完全覆盖一个月

    我在用着乔达时间 http www joda org joda time Java 中用于跟踪时间列表的库间隔 http www joda org joda time key interval html 我想检查是否有一个列表Interva
  • std::regex_match(和 std::regex_search)参数生命周期的限制

    考虑带有签名器的 C 11 函数std regex match std string const std smatch match std regex const re 什么 第一个参数的生命周期有限制吗 我没有找到 任何 但是当我执行以下
  • Firebase 存储 URL 不断随着新令牌的变化而变化

    我正在尝试使用 firebase 数据库和存储构建社交媒体应用程序 以下是预期的流程 用户上传个人资料图片 该图片存储在当前用户文件夹中的 Firebase 存储中 并且 URL 存储在 Firebase 数据库中以便快速访问 工作正常 用
  • 有没有一种方法可以在不使用angerlySetInnerHTML的情况下在文本中换行?

    我需要更换 n to br 但它是按照文本来理解的 我怎样才能做到这一点而不使用dangerouslySetInnerHTML 像平常一样插入文本 然后使用 CSS 修复换行符 http www w3schools com cssref p
  • LEFT JOIN 返回与 INNER JOIN 相同的结果

    我有一张桌子 磨砂膏 里面有 1600 个独特的物品 第二张桌子有100万以上 我运行 INNER JOIN 并获得 65 个匹配项 SELECT a BW Parent Number a Vendor Name b Parent Supp
  • 未向 HAL 提供足够的数据,预期位置

    我在 Android Studio 中收到此错误 我只想在按下按钮时打印文本 我收到以下错误 每次按下按钮时都会出现该错误 如果我取消注释掉意图 它也可以正常工作 但是我拥有的代码越多 错误更改就越多 我实际上不确定这是真正的错误 我这么说
  • 单击“提交”按钮时 jQuery Stop .blur() 事件

    我正在使用简单的演示电子邮件注册表单构建一个小型登陆页面 我想让表单字段在聚焦时打开 然后在模糊时缩小 然而 我面临的问题是 当您单击提交按钮时 这会引发模糊功能 隐藏按钮并缩小表单 我需要找到一种方法 仅当用户单击专注于提交按钮时停止 b
  • 图例中标签的悬停样式

    如何设置图例中标签的悬停样式 如果可以设置的话cursor default在此示例中 将鼠标悬停在 东京 纽约 柏林 伦敦 标签上http www highcharts com demo http www highcharts com de
  • 如何运行 Windows 批处理文件但隐藏命令窗口?

    如何运行 Windows 批处理文件但隐藏命令窗口 我不希望 cmd exe 在执行文件时在屏幕上可见 这可能吗 如果你写一个非托管程序并使用创建进程 https learn microsoft com en us windows win3
  • RecyclerView 滚动不适用于 NestedScrollView

    我有一个布局 其中有一个 NestedScrollView 其中包含一个图像 多个按钮和一个 RecycleView 当我说recyclerView smoothScrollToPosition or recyclerView scroll
  • 如何在 Flask/SQLAlchemy 中 select_lated() ?

    有以下型号 class Question db Model id db Column db Integer primary key True title db Column db String 125 text db Column db T
  • 防止表单提交时出现默认 jQuery

    这有什么问题吗 HTML
  • 显示模板中存储为二进制 blob 的图像

    我有一个模型 其中图像存储为二进制 blob 我想在模板中显示该图像以及有关该对象的其他数据 由于图像不是一个单独的文件 我不知道如何显示它 我尝试过设置标题 或使用send file or render template 但我要么没有得到
  • 如何使用FeatureUnion转换PipeLine中的多个特征?

    我有一个 pandas 数据框 其中包含有关用户发送的消息的信息 对于我的模型 我感兴趣的是预测消息的缺失收件人 即给定消息的收件人 A B C 我想预测还有谁应该成为收件人的一部分 我正在使用 OneVsRestClassifier 和
  • 从多个文件加载 Flask 配置

    我需要从多个文件加载配置 我使用下面的代码来加载一个文件 我应该反复使用它吗 如何加载多个配置 app Flask name app config from object yourapplication default settings 您
  • 收到 404 时模型的 EmberJS 路由

    同样的文本也在 EmberJS 讨论区中开放 我有以下路线 App IndexCrmPersonEditRoute Ember Route extend model function params var person this store
  • 如何使用 CSS 使表格中的分隔线/边框消失?

    我有一个简单的 HTML 表格 我希望分隔线 边框 消失 所需的最终结果是一个除了实际文本之外不可见的表格 我尝试将 border 属性设置为 0 但没有帮助 我应该使用什么正确的 CSS 属性 table tr td th border
  • 对 .NET Windows 安装程序应用程序执行注册表搜索

    我有一个 NET winform 安装程序应用程序 在安装之前 我会进行注册表搜索以检查计算机上是否安装了 MS Access Runtime 搜索目标机器 搜索目标机器的属性 启动条件 启动条件的属性 但是我想避免对路径进行硬编码 例如
  • SWIG 类型映射 uint8_t* 从 C/C++ 到 java.nio.ByteBuffer

    我正在尝试将输入和输出缓冲区从 C 传递给 java 类 出于效率原因 我需要使用 ByteBuffer 这两个缓冲区都是在 C 部分中分配的 我需要将它们传递给一个 java 函数 该函数将使用输入缓冲区进行一些计算并将结果写入输出缓冲区