关于不同编程语言相互调用的思考

简介: 关于不同编程语言相互调用的思考

1 思考历程

最近有些加我微信的知友私信我说,如何通过Qt调用python,如何通过java调用C++动态库等一系列的不同语言相互调用的问题。

关于这个问题,你只需要在百度搜索框中搜索,就会出来很多相关的帖子,但真正应用到自己系统中时,往往会遇到很多问题,比如环境、系统、兼容、版本问题等。这经常会耗费好几天的时间才能真正解决。

那对于这些问题,有没有一个通用的解决方案呢,我也思考了良久,现在也想通了一些,故分享给大家,也是对我自己做一次总结。

在开始之前,我想先总结下不同语言相互调用的方法

1)Qt调用Python:需要加载python库,及包含python的头文件

2)Python调用动态库:需导入ctypes模块,需要将python的数据类型转化为C或C++中的数据类型

3)Java调用动态库:需使用jni进行调用,也会涉及到数据类型相互转换

...

面对如此多的复杂方式,我们应该怎样才能提出一个通用的解决方案呢。


现在我们试想如果把两种编程语言设想成是两个应用程序,那么应用程序之间的交互应该如何处理,即进程之间应如何处理,这使我想到了IPC(进程间通信)

好,既然是IPC,那么IPC总共包含以下几种方式

01ebd755782e4c909dad0843d3544acf.jpeg

除去socket外,其它ipc方式,都会频繁的涉及到资源同步问题,而使用socket我们可以有效避免这类问题,且不需要处理复杂的数据类型转换。

为此,我们再进一步推演,既然是socket,那么有没有现成的框架或设计方式可以供我们参考,答案肯定是有的,那就是现在非常流行的C/S架构(不明白的可百度自行搜索)


2 为什么如此做

01ebd755782e4c909dad0843d3544acf.jpeg

参考上图:

我们将传统的语言相互调用的模式,转化成了C/S架构,总结起来可以有如下优点

1)屏蔽环境问题:不同语言相互调用的复杂环境问题,只需部署好各自的运行环境。例如:

a. 语言版本不兼容

b. 操作系统32位或64位兼容性问题

c. 调用的第三方库对环境有依赖

2)屏蔽语言数据类型差异:不需要对不同语言所支持的数据类型做转化,使用通用Json语言进行序列化或反序列化即可。例如:

a. 有符号和无符号之间的转换

b. 字符串宽窄字符转换

c. 不同编码类型的转换

3)应用隔离:两种语言是相互隔离的,在架构设计时,隔离性是必须要考虑到的。例如:

a. 当被调用的C++程序需要调用一个较新的功能或引用一个新的动态库,而使用此功能必须需要升级C++版本

b. 被调用方如果崩溃,会引起调用方崩溃

c. 可单独进行监控、自动化mock测试、代码优化

4)不必部署在同台机器上:socket连接可使两个应用单独部署,如果后期需要,可以不改变代码的情况下灵活切换。例如:

a. 调用其它语言一般是要进行复杂运算,为提高运算速度和稳定性,可将此部分灵活的切换到服务器上

b. 有些应用要求的磁盘或内存空间有限,需要将某些功能移动到服务器上,这样可有效减少体积

c. 某些应用并不想暴露过多的细节给客户,为安全考虑,可将这部分移动到服务器上单独部署

对于此种方式,有些同学可能会担心性能上的问题,一般情况下此种结构是部署在同机上的,对于现代硬件速度,这种差异几乎是可以忽略不计的。


3 如何做

既然好处这么多,那如何做呢

3.1 选择通信协议

既然是socket,那首先要考虑用什么协议,直接使用原生的socket,小豆君还是不太建议,这里你得处理很多跟应用无关的东西。鉴于是同机应用相互调用,使用websocket还是比较好的选择。

在不同的语言环境中,大家可以直接在百度搜索就可以看到很多关于websocket的调用方法,这里就不介绍了。

3.2 路由表

既然是服务端,就要对外提供接口,起初我们会这样定义:

{
    "interface": "getUserName",
    "params": {"userName": "wang"}
}
{
    "interface": "setSystemInfo",
    "params": {"sysName": "win"}
}

但是当你的接口增多时,这样的方式就会很混乱,所以你要将众多的接口进行分类整理,这时候就可以使用路由表,路由表可以使用“/”进行分隔,如

{
    "interface": "users/get/by/name",
    "params": {"userName": "wang"}
}
{
    "interface": "sys/set/all",
    "params": {"sysName": "win"}
}

注意此路由表不必与实际目录真实对应,此处仅表示逻辑对应

3.3 版本号

为了进行兼容,你应该在你的接口中增加版本号等兼容性信息,如果不填,则可以使用默认设置

3.4 为你的接口增加mock

增加mock单元测试,可以使你很容易的构造测试用例,并且保证代码有足够的稳定性


最后,每当我们工作中遇到问题时,百度出来的解决方案往往不适用当前环境,为此我们可能会花掉好几天的时间来解决问题,这是一个非常烦心的事情

为解决这种困境,小豆君会针对每个主题问题汇总到一篇文章中,当大家遇到问题时,只需要在我的这篇文章中查找即可解决,省时省力,同时也可以快速获取知识,提高工作效率,升职加薪(*^▽^*)


好了,关于今天的分享就到这里了,socket通信并不是万能的,还需根据实际情况进行综合考量。

互联网是开放开源的世界,每个有志有识之人都乐于分享,喜欢本文的你就支持一下吧

微信号:小豆君编程分享 (关注后,可加入小豆君交流群进行学习交流,也可第一时间看到最新文章)

头条号:小豆君编程分享

相关文章
|
6月前
|
Java Go C++
Go语言中的面向对象编程实践
【2月更文挑战第10天】本文将深入探讨在Go语言中如何进行面向对象编程实践。我们将了解如何在Go中实现封装、继承和多态,以及如何利用结构体、接口和方法来构建健壮和可维护的对象导向程序。通过实际代码示例,我们将更好地理解Go的OOP特性,并学习如何有效地运用它们。
|
6月前
|
设计模式 算法 Java
关于编程模式的总结与思考(上)
关于编程模式的总结与思考(上)
80 0
|
6月前
|
安全 Java Go
Go语言基础与面向对象编程概念
【2月更文挑战第10天】本文旨在介绍Go语言的基本特性和面向对象编程(OOP)的核心概念,以及如何将这两者结合起来。通过Go语言的结构体和方法实现封装、继承和多态,让读者深入理解面向对象编程在Go中的实现方式。文章适合对Go语言感兴趣的初学者和想要了解OOP在Go中如何应用的开发者。
|
3月前
|
安全 Java Go
为什么选择Go语言编写网络应用程序
为什么选择Go语言编写网络应用程序
|
5月前
|
Go
掌握Go语言:Go语言接口精解,实现多态性与灵活性的利器(31)
掌握Go语言:Go语言接口精解,实现多态性与灵活性的利器(31)
|
6月前
|
中间件 Go
Go语言中的中间件设计与实现
【5月更文挑战第4天】Go语言中的中间件在HTTP请求处理中扮演重要角色,提供了一种插入逻辑层的方式,便于实现日志、认证和限流等功能,而不增加核心代码复杂性。中间件遵循`http.Handler`接口,通过函数组合实现。常见问题包括错误处理(确保中间件能正确处理并传递错误)和请求上下文管理(使用`context.Context`共享数据以避免并发问题)。通过理解中间件机制和最佳实践,可以构建更健壮的Web应用。
147 0
|
6月前
|
Go
掌握Go语言:Go语言条件语句详解,掌握灵活的逻辑控制技巧(12)
掌握Go语言:Go语言条件语句详解,掌握灵活的逻辑控制技巧(12)
|
6月前
|
编译器 Go 持续交付
Go语言模块导入的实践与技巧:提升代码重用与模块化开发效率
【2月更文挑战第9天】在Go语言中,模块导入是实现代码重用和模块化开发的关键环节。本文将介绍Go语言中模块导入的实践与技巧,包括本地模块的导入、远程模块的导入、导入路径的解析与重定向、导入别名与包的重命名等,旨在帮助读者更加高效地进行Go语言的项目开发。
|
6月前
|
存储 NoSQL Java
关于编程模式的总结与思考(中)
关于编程模式的总结与思考(中)
43 1
|
6月前
|
存储 监控 NoSQL
关于编程模式的总结与思考(下)
关于编程模式的总结与思考(下)
55 0