SpringBoot调用python脚本及C++动态库方法

SpringBoot调用python脚本及C++方法

一、调用Python脚本

  • 使用下面的方法进行python脚本的调用
  • pythonExePath是python解释器的路径,比如D:/python_venv/Scripts/python.exe
  • pyFilePath是你要运行的py文件的路径,可以使用相对路径,比如./test_project/main.py
  • pythonParams是自定义的要传输的变量,需要在python程序中进行设置
	@SneakyThrows
    // use python function
    public void usePython(String pythonExePath, String pyFilePath, String pythonParams) {

        Process proc;

        try {

            proc = Runtime.getRuntime().exec(pythonExePath+" "+pyFilePath+pythonParams);

            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));

            String line = null;

            while ((line = in.readLine()) != null) {

                System.out.println(line);

            }

            in.close();

            proc.waitFor();

        } catch (IOException | InterruptedException e) {

            e.printStackTrace();

        }

    }
  • pythonParams自定义参数设置方法
# -*- coding: utf8 -*-

# package import
import argparse
from services.operate_satellite_data import OperateSatelliteData
from services.operate_log_data import OperateLogData


# create class SettingParams
class SettingParams:
    def __init__(self):
        self.parser = argparse.ArgumentParser(description='setting python params')
        self.args = None

    # setting operate params function
    def setting_params(self):

		# 必选参数设置
        self.parser.add_argument('parse_type', choices=['satellite', 'log_compare'], type=str, help='处理类别')

		# 可选参数设置,可选参数设置时候必须要"--",只有这样才能识别出来是可选参数
        self.parser.add_argument('-fp', '--file_path', type=str, help='文件路径')

        self.parser.add_argument('-fn', '--file_name', type=str, help='文件名称')

        self.parser.add_argument('-eft', '--export_file_type', choices=['json', 'txt', 'csv'], type=str, help='输出文件类别')

        self.parser.add_argument('-efp', '--export_file_path', default='', type=str, help='输出文件路径')

        self.parser.add_argument('-efn', '--export_file_name', type=str, help='输出文件名称')

        self.args = self.parser.parse_args()

        if self.args.export_file_path == '':

            self.args.export_file_path = self.args.file_path

        return self.args


if __name__ == '__main__':

    args = SettingParams().setting_params()

    if args is not None:

		# 调用参数时,用args.parse_type这种方式进行调用
        if args.parse_type == 'satellite':

            pass

        elif args.parse_type == 'log_compare':

            pass

二、调用C++

  • SpringBoot调用C++算法的话,可以通过调用动态库或可执行文件进行实现

2.1 调用C++打包好的Dll动态库

  • 通过下面的代码在pom.xml中配置JNA
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.9.0</version>
</dependency>
  • 建立连接Dll库的Mapper文件
package com.mbtxtq.app.mapper.dll;

import com.sun.jna.Library;
import com.sun.jna.Pointer;

public interface MyLibraryMapper extends Library {

	// 里面的方法名称和数据类型要与Dll库里的方法名称和数据类型保持一致
	// int 对应 int;char* 对应 String;char* 数据对应 Pointer
	
    public int GetHdNum1(int firstNum, int secondNum);

    public boolean GetHardwareNum(String a, Pointer b);

    public Pointer GetHdNumS(String data);

}
  • Dao层建立读取Dll库方法的类
package com.mbtxtq.app.dao.dll;

import com.mbtxtq.app.mapper.dll.MyLibraryMapper;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import lombok.SneakyThrows;
import org.springframework.stereotype.Repository;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

@Repository
public class MyLibraryDataOperate {

    @SneakyThrows
    public Object useMyLibraryDll(String dllPath, String funcName, ArrayList<Object> paramArray) {

        MyLibraryMapper myLibrary = Native.load(dllPath, MyLibraryMapper.class);

        if (funcName.equals("GetHdNum1")) {

            return myLibrary.GetHdNum1((Integer) paramArray.get(0), (Integer) paramArray.get(1));

        } else if (funcName.equals("GetHdNumS")) {

            Pointer result = myLibrary.GetHdNumS((String) paramArray.get(0));

            StringBuilder data = new StringBuilder();

            for (int i=0, length=1024; i < length; i++) {

                String innerData = String.valueOf((char) result.getByteArray(0, 1024)[i]);

                data.append(innerData);

            }

            return data.toString();

        } else if (funcName.equals("GetHardwareNum")){

            Pointer p = new Memory(1024);

            boolean result = myLibrary.GetHardwareNum((String) paramArray.get(0), p);

            StringBuilder data = new StringBuilder();

            for (int i=0, length=1024; i < length; i++) {

                String innerData = String.valueOf((char) p.getByteArray(0, 1024)[i]);

                data.append(innerData);

            }

            return data.toString().getBytes(StandardCharsets.ISO_8859_1);

        } else {

            return null;

        }

    }

}

  • 然后直接调用MyLibraryDataOperate里的useMyLibraryDll方法即可

2.2 调用C++打包好的exe可执行文件

  • 直接使用下面方法调用即可
public void openExe(FileNameAo fileName) throws IOException, InterruptedException {
        
        Runtime runtime = Runtime.getRuntime();//启动程序最主要的类 RunTime
        String fName = fileName.getFileName(); //程序名作为参数
        runtime.exec("D:\\"+ fName +"\\" + fName + ".exe"); //程序所在位置

}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arthur Morgen06

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值