Swig/CPP2Java

news2024/9/22 19:44:38

简介

实际工程可能存在如下部分:业务接口需要编程高效的语言(如Python、Java等),易于部署维护;而核心算法部分,某些场景需要高效计算,会使用性能高效的语言(如C/C++等)。

对于上述场景,“粘合剂”工具可以将语言打包,实现跨语言调用。例如Java/Python可以使用Swig转换后的C/C++代码,Python可以使用JPype等调用Java代码。这种跨语言调用的场景能帮助我们解决例如不同语言间性能差异、存量代码等问题。

本文主要记录、介绍使用Swig工具转换C++为Java代码中的一些常用技巧、问题及其解决方式等。

官方手册

Swig(4.0)用户手册:

SWIG Users Manualhttps://www.swig.org/Doc4.0/Contents.html#Contents

环境搭建&基础

朋友分享的Swig入门教程,此处不再赘述:

Swig超详细入门教程(Java调用C/C++, CMake)——更新于2021.12_ymzhu385的博客-CSDN博客_swig教程

Java-Cpp(包含了Swig/Jna/Jni)的Example代码,在github有个较为全面的仓库:

GitHub - remram44/java-cpp-example: Example of using C++ classes from Java. Showcases SWIG, JNA and JNI

本文后续的代码将以该github的exmaple代码为基础,进行扩展

Cpp2Java工程模板

Swig工程构建相对比较简单:

输入:
    C/C++代码 + cpp2java.i(Swig语法文件)
输出:
    Java代码(对应语言的代码)

所以我们的主要目的是学习cpp2java.i如何编写。想要全面学习swig/java .i语法的同学可以参看上文提到的官方手册,或相关开源项目,例如:

开源项目主要.i链接
Google OR-Toolsor-tools/constraint_solver.i at stable · google/or-tools · GitHub
libtorrent4jhttps://github.com/aldenml/libtorrent4j/blob/master/swig/libtorrent.i

本文摘要部分常用功能(语法)。

常用关键词概述

关键词概述
include基础关键词,可以关联多个.i文件,与C++中inlcude类似
template最常见的使用方式是template转换stl中的容器类(例如vector等)
extend在目标语言(java)扩展自定义类接口(不影响C++代码)
pragma(java)

%pragma(java) jniclassimports 可以为JNI添加import

%pragma(java) jniclasscode 可在JNI中插入java代码

typemap

typemap可以自定义跨语言数据转换,例如java中的int,在特定的场景下可在C++中自定义转换为long long(是否有必要有待商榷)。

参考:Typemaps

常用C++容器转换

在官方手册中,提供了一份较为常见的转换表:

核心思想是具体化C/C++容器中的模板,例如set<T> -> set<int>等。大部分容器均可通过类似方法转换:

%include "std_vector.i"
%include "std_string.i"
%include "std_map.i"

namespace std {
    %template(IntVector) vector<int>;
    %template(Str2StrMap) std::map<std::string, std::string>;
};

类型扩展

部分场景,我们需要为自定义类(或依赖类)在Java中添加或重命名接口,例如c++中的map使用[]随机访问,而在java中可以重载为get访问。如下是开源仓库(libtorrent4j,boost_map.i)的案例:

namespace boost {
namespace container {

template<class Key, class T>
class map
{
public:

    bool empty() const;
    void clear();
    std::int64_t size() const;

    %extend
    {
        # ...

        T& get(Key const& k)
        {
            return $self->operator[](k);
        }

        # ...
    }
};

}}

代码块

swig提供使用

%pragma(java) jniclasscode

添加内嵌代码块,一个较为常用的场景是加载动态库,例如官方文档中提到的

%pragma(java) jniclasscode=%{
  static {
    try {
      System.loadLibrary("example");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. \n" + e);
      System.exit(1);
    }
  }
%}

当需要在静态代码段中import不同包的类时,例如xgboost(XGBoostJNI)的 NativeLibLoader(XGBoost中NativeLibLoader与XGBoostJNI在同一个包中,不需要导入):

  static {
    try {
      NativeLibLoader.initXGBoost();
    } catch (Exception ex) {
      logger.error("Failed to load native library", ex);
      throw new RuntimeException(ex);
    }
  }

使用如下关键词import NativeLibLoader

%pragma(java) jniclassimports
%pragma(java) jniclassimports=%{
import ml.dmlc.xgboost4j.java.NativeLibLoader;
%}

常见问题

1. CMakeList-JDK环境问题

Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
  JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)

主要是CMake没识别到Java环境路径(或没安装),导致以下语句出错了

FIND_PACKAGE(JNI REQUIRED)

Stackoverflow上比较全面的回答了:

java - CMake could not find JNI - Stack Overflow

这边补充一个方案(部分用WSL1的同学即是设置了JAVA_HOME可能也找不到路径):

set(JAVA_DIR "your/jdk/path")

set(JAVA_AWT_LIBRARY "${JAVA_DIR}/lib/libjawt.so")
set(JAVA_JVM_LIBRARY "${JAVA_DIR}/lib/server/libjvm.so")
set(JAVA_INCLUDE_PATH "${JAVA_DIR}/include")
set(JAVA_INCLUDE_PATH2 "${JAVA_DIR}/include/linux")
set(JAVA_AWT_INCLUDE_PATH "${JAVA_DIR}/include")

2. operator异常:

Warning 503: Can't wrap 'operator =' unless renamed to a valid identifier.

可选择如下方式处理:

%rename(eq) operator==;

# or 

%ignore operator=;

Reference

[1] SWIG Users Manual

[2] GitHub - google/or-tools: Google's Operations Research tools

[3] https://github.com/dmlc/xgboost

[4] https://github.com/aldenml/libtorrent4j

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/181970.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超详细Netty入门,看这篇就够了!

简介&#xff1a; 本文主要讲述Netty框架的一些特性以及重要组件&#xff0c;希望看完之后能对Netty框架有一个比较直观的感受&#xff0c;希望能帮助读者快速入门Netty&#xff0c;减少一些弯路。 前言 本文主要讲述Netty框架的一些特性以及重要组件&#xff0c;希望看完之后…

一起自学SLAM算法:10.2 VINS算法

连载文章&#xff0c;长期更新&#xff0c;欢迎关注&#xff1a; 不管是激光SLAM还是视觉SLAM&#xff0c;由于传感器采样率、传感器测量精度、主机计算力等因素的限制&#xff0c;在高速运动状态下定位追踪极易丢失。虽然轮式里程计能为激光SLAM系统提供短期运动预测以避免高速…

记录一次ubuntu进入不了界面的恢复记录

能说服一个人的从来不是道理&#xff0c;而是南墙&#xff1b;能点醒一个人的从来不是说教&#xff0c;而是磨难 一、问题描述 1、 卸载Python之后&#xff0c;ubuntu启动进入黑屏tty界面无法联网&#xff0c;无法进入桌面 2、 进入到界面之后没有网络&#xff0c;网络中或者右…

【分析向】没有三级缓存会导致什么?

通过上篇&#xff08;【实践向】当移除了三级缓存…… &#xff09;的实践&#xff0c;我们得出的结论是&#xff1a;如果不存在代理对象&#xff0c;二级缓存就可以解决循环依赖性的问题&#xff0c;但是当存在代理对象的时候&#xff0c;二级缓存则无法完全解决循环依赖&…

机器自动翻译古文拼音 - 十大宋词 - ALL

机器自动翻译古文拼音 - 十大宋词 - 雨霖铃寒蝉凄切 柳永https://mp.csdn.net/mp_blog/creation/editor/128779245机器自动翻译古文拼音 - 十大宋词 - 江城子乙卯正月二十日夜记梦 苏轼https://mp.csdn.net/mp_blog/creation/editor/128779156机器自动翻译古文拼音 - 十大宋词 …

0基础小白十分钟入门人工智能强化学习(附有实战源码)

强化学习概述 1.1 强化学习的学习任务目标 强化学习&#xff08;Reinforcement Learning, RL&#xff09;&#xff0c;用官话讲&#xff0c;是机器学习的范式和方法论之一&#xff0c;用于描述和解决智能体&#xff08;agent&#xff09;在与环境的交互过程中通过学习策略以达成…

Mybatis-Plus 乐观锁与代码生成器

目录 乐观锁 问题引入 乐观锁实现思路 实现步骤 代码生成器 代码生成器分析 代码生成器实现 乐观锁 问题引入 业务并发现象带来的问题:秒杀 假如有100个商品或者票在出售&#xff0c;为了能保证每个商品或者票只能被一个人购买&#xff0c;如何保证不会出现超买或者重复…

记一次nginx崩溃事件

一、事件描述 2023年春节复工第一天&#xff0c;项目组同事反馈说业务系统中图像处理代理Nginx服务于1月23日发生崩溃&#xff0c;完成了重启操作&#xff0c;检查nginx的日志有如下报错&#xff1a; 2023/01/23 11:07:07 [crit] 3237#3237: *2253009 pwritev() "/var/c…

网络编程-----(Socket编程TCP)

在咱们的TCP API中&#xff0c;也是主要是涉及到两个类: 1)ServerSocket:主要是给TCP服务器来进行使用的&#xff1b; 2)Socket:我们既需要给客户端来进行使用&#xff0c;也需要给服务器来进行使用&#xff1b; 这样就是说我们是不需要使用专门的类来进行表示传输的包&#x…

Java学习之抽象模板模式

目录 一、基本介绍 二、模板设计模式能解决的问题 三、最佳实践 一、AA类 二、BB类 三、main方法实现 四、提取相同语句 五、建立继承关系 父类-Template 子类-AA类 子类-BB类 六、运行中的动态绑定机制 一、基本介绍 抽象类体现的就是一种模板模式的设计&#xff…

【Git】概述

目录 1.1 是什么 介绍 历史时间轴 版本控制工具 1.2 能干嘛 作用 Git工作机制 代码托管中心 集中式版本控制系统 分布式版本控制系统 1.3 去哪下 命令行工具&#xff1a;Git for windows 操作系统中可视化工具&#xff1a;TortoiseGit(了解) GitHub网站 1.1 是什…

带你走进Java8新特性Stream流的小世界

目录 一. 什么是流&#xff08;Stream&#xff09; 1.1 流的定义 1.2 流的特点 1.3 操作流 1.4 创建流 二. 流的中间操作 2.1 流的筛选与切片 2.1.1 filter 2.1.2 limit 2.1.3 skip 2.1.4 distinct 2.2 流的映射 2.2.1 map 2.2.2 flatMap 2.3 流的排序 2.3.1 s…

智公网:2023年教师编必背30考点

1、制度化教育阶段开始于&#xff1a;近代。 2、各国的学校教育系统基本形成于&#xff1a;19世纪末。 3、现在世界上大多数国家的义务教育年限在&#xff1a;9年或9年以上。 4、“不愤不启&#xff0c;不悱不发”启发教学法的最早倡导者是&#xff1a;孔子。 5、“建国君民…

【Spring】Spring 6 新特性一一HTTP Interface

简介 Spring 6 的第一个 GA 版本发布了&#xff0c;其中带来了一个新的特性——HTTP Interface。 这个新特性&#xff0c;可以让开发者将 HTTP 服务&#xff0c;定义成一个包含特定注解标记的方法的 Java 接口&#xff0c;然后通过对接口方法的调用&#xff0c;完成 HTTP 请求…

硬盘损坏数据恢复怎么操作?恢复数据的常用方法

硬盘一般固定在电脑里面的存储装置&#xff0c;里面保存着我们大量的数据。随着电脑的使用越加广泛&#xff0c;有时不免出现一些问题&#xff0c;比如硬盘在使用过程中出现数据错误&#xff0c;或者是硬盘的内部零件出现故障。出现这些问题&#xff0c;硬盘损坏数据恢复怎么操…

Redis实现UV统计 | 黑马点评

一、HyperLogLog 1、为什么用HyperLogLog 先介绍两个概念&#xff1a; UV&#xff1a;全称 Unique Visitor&#xff0c;也叫独立访客量&#xff0c;是指通过互联网访问、浏览这个网页的自然人、1 天内同一个用户多次访问该网站&#xff0c;只记录 1 次。PV&#xff1a;全称 …

车载以太网 - SomeIP测试专栏 - 总纲

关于车载以太网中的SomeIP在网上也逐渐有越来越多的资料,讲的也是非常好;但是个人认为讲的泛,很难让初学者或者初入门者真正了解SomeIP到底是一个什么东西,以及它究竟在车载上有什么作用,本专栏会由浅入深的讲解SomeIP整个协议内容规范,并且对Tc8中SomeIP相关的协议测试用…

实习日记!

目录 http://localhost:5789实习第三天 接下来几天的target 实习第四天 Git的操作 实习第五天 12月5日-Mon 12月6日 12月9日 12月12日 12月15日 useState() hook 12月16日 useEffect() hook async 函数 异步编程 回调函数 12月17日 C#中的&#xff1f;&#x…

postgresql源码学习(54)—— HotStandby从库必须设置大于等于主库的参数

新的一篇本来计划研究lazy_scan_heap函数&#xff0c;但过于复杂还没研究出来… 下午做题遇到一个这样的问题&#xff0c;之前没太关注过&#xff0c;打算学习学习&#xff0c;避免主从配置踩坑。 题干搜一搜&#xff0c;没搜出啥有用的玩意…渣翻成英文搜一搜&#xff0c;搜出…

windows搭建go语言开发环境,IDEA安装go插件并运行Hello world代码

2023年1月27日1.Windows上安装Go语言开发包参考链接&#xff1a;http://c.biancheng.net/view/3992.html1.1.下载Go语言开发包可以在Go语言官网 &#xff08;https://golang.google.cn/dl/&#xff09; 下载Windows 系统下的Go语言开发包&#xff0c;如下图所示。这里我们下载的…