【OpenIM原创】C/C++调用golang函数,golang回调C/C++函数

【原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型 【原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型 1、内容概述 一套完整IM系统中,除开基本的业务设计,消息模型的设计是其中最为关键的一环,它关系到整个IM系统的可靠性、高效性、稳定性,因此需要设计一套合理的消息传递收发机制以承载IM的各种需求,OpenIM结合具体的业务场景,提炼出IM后端的重要接口,并经过反复推敲,验证,设计出了自己的一套通信协议OMTP,协议中每个字段尽量的减少冗余,使其精简高效、最大限度的满足现有的业务需求并能够支持业务的水平拓展,同时为了达到消息的实时可靠与高效, 阅读详情

需求来源

Open-IM 是由前微信技术专家打造的全开源、永久免费、无限制的即时通讯组件。Open-IM 包括 IM 服务端和客户端 SDK,实现了高性能、轻量级、易扩展等重要特性。开发者通过集成 Open-IM 组件,并私有化部署服务端,可以将即时通讯、实时网络能力免费、快速集成到自身应用中,并确保业务数据的安全性和私密性。

OpenIM包括Server和SDK,两者都是采用golang实现的,移动端通过gomobile生成代码,再加上对应的插件,这样能适应多个前端开发框架,无论是原生的iOS、Android还是跨端开发的Flutter、uniapp、react native、cordova等。OpenIM SDK 要用在pc端electron框架中,先解决C调用golang的问题,再打通nodejs调用C /C++,当然这里还涉及到各种回调函数。

img

网上有很多例子告诉你怎么从Go语言调用C /C++语言的函数,但少文章有告诉你,如何从C /C++语言函数中调用Golang语言写的函数。本文通过实际代码,来展示两个能力:(1)golang如何编译成动态库so (2)C /C++如何调用golang函数 (3)golang如何调用C /C++的回调函数。

goland代码及注意事项

a.go代码:

package main
/*
#cgo CFLAGS: -I .
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef void (*callback)(void *,int);
extern void c_callback (void *,int);
extern callback _cb;
*/
import "C"
import (
    "sync"
    "unsafe"
    "time"
    "fmt"
    "encoding/json"
)

var mutex  sync.Mutex 


type HelloWorld  interface {
      OnSuccessCallback(result string)
}

func doSomething(worker HelloWorld, input string){
    //模拟异步
    go func() {
        fmt.Println("func doSomething start...")
        time.Sleep(time.Duration(2)*time.Second)
        fmt.Println("func doSomething end...")
        result := "do something successful"
        worker.OnSuccessCallback(result)
    }()
}

type SomeHelloWorld struct {
    cb C.callback
    input string
    passBackData string
}

type CallbackOutput struct {
    Data     string   `json:"data"`
    Output   string `json:"output"`
}


func(t *SomeHelloWorld) OnSuccessCallback(result string){
    var callbackOutput CallbackOutput
    callbackOutput.Data = t.passBackData
    callbackOutput.Output = result

    jsonStr, err := json.Marshal(callbackOutput)
    if err != nil {
        fmt.Println("err: ", err.Error())
    }
    fmt.Println("json: ", string(jsonStr))

    var cmsg *C.char = C.CString(string(jsonStr))
    var ivalue C.int = C.int(len(jsonStr))
    defer C.free(unsafe.Pointer(cmsg))
    //C._cb全局变量,再回调时加锁互斥
    mutex.Lock()
    defer mutex.Unlock()
    C._cb = t.cb
    C.c_callback(unsafe.Pointer(cmsg), ivalue)
}

//export  doSomethingCallback
func doSomethingCallback(p C.callback, input *C.char, data *C.char){
    var one SomeHelloWorld
    one.cb = p
    one.passBackData = C.GoString(data)
    one.input = C.GoString(input)
    fmt.Println("one: ", one)
    doSomething(&one, one.input)
}

func main() {
}

在代码块,有几个点需要注意:

(1)package main 这个必须是main

(2)这个注释不能少,原封不动复制粘贴即可

/* #cgo CFLAGS: -I . #include <stdio.h> #include <string.h> #include <stdlib.h> typedef void (*callback)(void *,int); extern void c_callback (void *,int); extern callback _cb; */

(3)对于提供给C调用的函数,在函数上一行加上export 例如://export doSomethingCallback

(4) main函数保留

func main() { }

b.go代码

package main

/*
#include <stdio.h>

typedef void (*callback)(void *,int);

callback _cb;

void c_callback(void* p,int i)
{
    _cb(p,i);
}
*/
import "C"

原封不动保存就可以了。

编译成动态库

go build -o libcallback.so  -buildmode=c-shared a.go b.go

img

生成libcallback.h 和libcallback.so

C代码调用

#include <stdio.h>
#include <unistd.h>

#include "libcallback.h"

void gocallback(void* s,int len) {

    printf("%s\n", (char*)s);

}

int main() {
    const char* a = "cstring input";
    doSomethingCallback(gocallback, (char*)"cstring hello", (char*)a);
    pause();
}

编译

gcc -v  m.cpp  -o m ./libcallback.so 

生成可执行程序 m

img

输入./m 执行,C调用golang的doSomethingCallback函数,并在此函数回调C的gocallback函数,完成了C->golang->C

img

小节

github源代码下载

OpemIM开源IM项目

OpenIM官网

C和golang互调能力打通,这样,对于采用C/C++开发的项目,如果某些业务特性不追求性能上的机制,可以通过golang实现,这样达到了开发效率和执行效率的平衡,对业务开发非常有帮助。

通过深度调用机制分析,无论是Go调用C,还是C调用Go,其需要解决的核心问题其实都是提供一个C/Go的运行环境来执行相应的代码。Go的代码执行环境就是goroutine以及Go的runtime,而C的执行环境需要一个不使用分段的栈,并且执行C代码的goroutine需要暂时地脱离调度器的管理。

img

要达到这些要求,运行时提供的支持就是切换栈,以及runtime.entersyscall。在Go中调用C函数时,runtime.cgocall中调用entersyscall脱离调度器管理。runtime.asmcgocall切换到m的g0栈,于是得到C的运行环境。在C中调用Go函数时,crosscall2解决gcc编译到6c编译之间的调用协议问题。cgocallback切换回goroutine栈。runtime.cgocallbackg中调用exitsyscall恢复Go的运行环境

OpenIMgithub开源地址:

https://github.com/OpenIMSDK/Open-IM-Server

OpenIM官网 : https://www.rentsoft.cn

**OpenIM官方论坛: ** https://forum.rentsoft.cn/

更多技术文章:

开源OpenIM:高性能、可伸缩、易扩展的即时通讯架构
https://forum.rentsoft.cn/thread/3

【OpenIM原创】简单轻松入门 一文讲解WebRTC实现1对1音视频通信原理
https://forum.rentsoft.cn/thread/4

【OpenIM原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型
https://forum.rentsoft.cn/thread/1

【一文通】C/C++与Go语言混合编程入门级教程(Windows平台完成) Go语言可以通过自带的 cgo 工具进行 C+GO 混合编程,但在实践上可能会遇到很多坑,本文仅从 Hello World 的难度系数来实际体验 cgo ,免除大家前期遇坑后无法继续的苦恼。 阅读详情

相关推荐

社交交友源码解析:双端原生IM与音视频通话架构设计

在移动社交领域,即时通讯(IM)和音视频通话能力是产品体验的基石。从基础概念来看,IM系统需要解决长连接维护、消息可靠传输与服务端时序控制等核心问题,而语音视频通话则涉及信令协商、媒体传输与音频焦点管理等底层机制。理解这些技术原理,有助于评估一套双端原生APP源码的工程价值。在实际业务中,一套完整的陌生人社交解决方案,通常包含用户匹配、实时聊天、一对一通话、直播间互动等多个模块,其架构选型直接决定了后续的扩展成本与运营稳定性。同时,原生开发在音视频性能、Android后台保活及隐私合规方面具备显著优势。无论

weixin_34054931的博客 453

C/C++代码中调用golang的接口。

一、C代码调用go接口。 1、前提是golang已经可以提供一些接口,此时需要在C代码中调用这些接口。或者第三方模块是golang写的,则需要把第三方编译成so文件,然后再C代码汇总访问其暴露出来的接口。 比如这里我让golang代码提供函数功能,并且将自己编译成so动态链接库,在C代码中调用这个库中的接口。 1.1、 golang提供的接口,文件名:autolibary.go,注意这里“//export Func”这句话一定要有,否则一会链接找不到接口。 package main impor.

weixin_37871174的博客 5596

C++调用Go方法的字符串传递问题及解决方案

摘要:C++调用Go方法时,字符串参数的内存管理需要由Go侧进行深度值拷贝。 现象 在一个APP技术项目中,子进程按请求加载Go的ServiceModule,将需要拉起的ServiceModule信息传递给Go的Loader,存在C++调用Go方法,传递字符串的场景。 方案验证时,发现有奇怪的将std::string对象的内容传递给Go方法后,在Go方法协程中取到的值与预期不一致。 经过一段时间的分析和验证,终于理解问题产生的原因并给出解决方案,现分享如下。 背景知识 Go有自己的内存回收GC机制,通过make等申请的内存不需要手动释放。 C++中为std::string变量赋值

先学python再学java-已学php再学java还是python?

在考虑学java还是python之前先来说说二者的应用领域。Python的主要应用方向:1、科学计算随着NumPy,SciPy,Matplotlib,Enthoughtlibrarys等众多程序库的开发,Python越来越适合于做科学计算、绘制高质量的2D和3D图像。和科学计算领域最流行的商业软件Matlab相比,Python是一门通用的程序设计语言,比Matlab所采用的脚本语言的应用范围更广泛...

weixin_37988176的博客 466

ROS 2实战:用MoveIt Task Constructor让机械臂完成抓取任务(附避坑指南)

本文详细介绍了如何在ROS 2环境中使用MoveIt Task Constructor框架,为Franka Panda机械臂构建一个完整的拾取放置任务流水线。通过分解任务阶段、配置规划器并处理实际部署中的常见问题,帮助开发者从基础运动规划升级到可靠的多步骤任务编排,并附有核心避坑指南。

vvv99的博客 505

Python实现微信PC端聊天记录自动化监听与智能回复

本文详细介绍了如何使用Python实现微信PC端聊天记录的自动化监听与智能回复。通过win32api和uiautomation库,模拟人工操作,实时监控聊天窗口并抓取新消息。文章重点讲解了核心代码逻辑、环境搭建步骤,并提供了实现关键词触发自动回复的完整方案,旨在提高工作效率与信息管理自动化水平。

weixin_29092031的博客 345

【无标题】好消息 突破:IM开源项目OpenIM采用wasm技术实现jssdk

好消息 突破:IM开源项目OpenIM采用wasm技术实现jssdk

OpenIM的博客 1652

FeynRules的上手使用3--运行

FeynRules的运行 接上两篇,在我们正确的设定模型参数和拉氏量之后,就可以运行FeynRules来推导费曼规则。 装载文件 首先需要设定FeynRules文件所在位置,并装载FeynRules模块: $FeynRulesPath = SetDirectory[ ] << FeynRules` 接下来是装载写好的模型文件: LoadModel[ < file.fr >, < file2.fr >, … ] 模型文件后缀为".fr",可以分几块构成。模型描述可以写在

cool_bot的博客 1074

即时通讯(IM)开源项目OpenIM对WebAssembly支持,提升web端体验

2019 年 12 月,W3C 标准批准了第四种官方语言:WebAssembly (Wasm)。这种语言在结构、使用和功能方面与以前的语言有很大不同。WebAssembly 是一种新的编码方式,可以在现代的Web浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C / C ++等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。

OpenIM的博客 2654

【2024保研经验帖】中科院信工所夏令营经验分享

中科院信工所夏令营经验分享,信工所夏令营据说只要报了就能进,这个是不是真的尚不清楚,不过qq群里有八九百个人,也属实可怕。招生老师说我们这届夏令营招200-300个左右,于是又开始惶惶不安。 夏令营时期都是线上进行,先是每个科室进行线上招生宣讲,然后报名第一志愿部门和第二志愿部门,不同部门的考核是不同的。有的部门只要求英语面试和综合面试,有的部门除了面试还需要机试,而有的部门除了这些还需要笔试。

m0_63002183的博客 4489

扩增子测序|iCAMP包——基于系统发育零模型分析确定性和随机性在群落构建过程R中实践

iCAMP的核心功能是通过系统发育分箱的零模型分析,量化不同生态过程的相对重要性。,用于评估不同生态过程(同质选择、异质选择、扩散和漂变)对整个群落及各个系统发育分箱(bin)的相对重要性。该方法也成为nature,science系列文章的常客,深受大家喜欢,在文章中运用该方法将为论文增色不少。外环和内环的圆环图显示了每个门(或变形菌门的分类)中不同过程的相对重要性。中央是系统发育树,内环展示了不同过程的相对重要性,表示每个系统发育箱中的DL。示例代码中提供了数据和代码,已经小编测试,可直接运行。

weixin_46814750的博客 6227

Golang正确使用kafka的姿势-细节决定成败

本文转自 跟我学IM后台开发作者 杰克.许 经OpenIM技术人员整理修订后发布。 写在前面 Open-IM是由前微信技术专家打造的开源的即时通讯组件。Open-IM包括IM服务端和客户端SDK,实现了高性能、轻量级、易扩展等重要特性。开发者通过集成Open-IM组件,并私有化部署服务端,可以将即时通讯、实时网络能力快速集成到自身应用中,并确保业务数据的安全性和私密性。 Kafka在OpenIM项目中承担重要的角色,感谢作者在使用OpenIM中发现的bug(使用Kafka不当的bug) 了解更多原创文章:

OpenIM的博客 1253

Deep SHAP 深度学习模型的可解释性分析

Deep SHAP 算法是一种用于解释深度学习模型的技术, 该算法通过将每个特征的重要性与输出值相关联来进行解释。本博客对深度学习的模型可解释性进行了分析。

cnjs1994的博客 5119

2020年常用websocket开源库整理汇总

websocket是html5中新增的协议,websocket的特点是全双工,服务端和客户端可以互相发送消息。得益于不同平台对WebSocket协议的广泛实现,它为跨多种平台的实时网络应用程序开发提供了极大的方便。除了可以在前端开发的JavaScript 中使用 WebSocket 之外,我们也可以在 Java、C++、Go、Rust 等编程语言平台中使用 WebSocket。 我汇总整理了8...

jonychen1的博客 1万+

《Python Web项目集锦》-专栏介绍和目录

本专栏专注于Python Web项目,涉及内容包含FastAPI、Django、Flask等,所有项目代码完整且可直接运行。不管是零基础还是有经验的开发,相信都能从本专栏获益。有任何问题欢迎私聊博主,专栏持续更新中...

数据知道的博客 5211

LeRobot 入门教程(七)数据集

LeRobot Dataset v3.0 是机器人学习数据的标准化格式,支持多模态时间序列数据和视频的统一访问。该版本通过基于文件的存储(Parquet/MP4)、关联元数据和Hub原生流式处理等新特性,显著提升了性能并降低了存储开销。文档详细介绍了格式设计、安装使用、数据记录与加载方法,以及从v2.1迁移到v3.0的步骤,特别针对大型数据集(如DROID 1.0.1)的处理提供了SLURM集群移植方案。v3.0通过优化文件组织和元数据管理,实现了更快的加载速度、更高的内存效率和更好的可扩展性。

2506_90492529的博客 2052

C/C++调用Golang 二

C/C++调用Golang 二 《C/C++调用Golang 一》简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用。本文总结具体项目中的使用场景,将介绍三种较复杂的调用方式:一,C++向golang传入复杂结构体;二,C++向golang传入回调函数,在golang中调用C++函数;三,C++调用golang函数,返回复杂的结构体。 (本文后面涉及三个例子,省略了编译步...

weixin_30929195的博客 1066

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C语言竟可以调用Go语言函数,这是如何实现的?

大家好,我是飞哥!今天和大家聊一个问题,一门语言是否可以在同一个进程内调用另外一门语言实现的函数?例如 C 语言是否可以调用 Golang 实现的函数?注意我说的是同进程内调用,跨进程的 IPC、PRC 之类的技术不算。直接抛出这个问题的答案,同进程跨语言调用是可行的。在各种语言设计时,为了复用其它语言生态中积累下来的大量的代码资产,都会实现跨语言调用的机制。例如在 Golang 中,实现了 cg...

zhangyanfei01的专栏 973

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【C++调用Go方法的字符串传递问题及解决方案】【转载】

3. go build -buildmode=c-shared .生成的.h头文件中定义了C++中Go的变量类型的定义映射关系,比如GoString、GoInt等。在一个APP技术项目中,子进程按请求加载Go的ServiceModule,将需要拉起的ServiceModule信息传递给Go的Loader,存在C++调用Go方法,传递字符串的场景。在C++代码中,任何对成员p的char*指针的操作,都将直接影响到Go中的string对象的值。程序执行结果:​​​​​​​。Go侧代码:​​​​​​​。

j8267643的博客 533

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C/C++调用Golang 一

C/C++调用Golang 一 (开发环境: 操作系统: windows 7 32位操作系统 C++: visual studio 2010 Golang:go version go1.9 windows/386 TDM-GCC-32) 用一个简单的例子演示如何在C++中调用golang程序。用golang编写一个简单的函数,编译成动态链接库...

weixin_30876945的博客 1925

GO 和C 的相互调用(1)

爱上了Golang,C/C++ 又不想放弃。好在Go 语言提供了和C语言相互调用的机制(CGO )。包括下面机构问题 C/C++ 调用Go 程序编写的库。 go 语言调用C/C++ 动态和静态库。 go 语言调用 C语言的回调程序(Callback) 函数之间传递参数 本文先讨论前面两个问题。 C/C++ 调用 Go 首先写一个go 程序 package main import "C" import ( "fmt" ) //export Foo func ...

姚家湾博客 3004

全面总结: Golang 调用 C/C++,例子式教程

大部分人学习或者使用某样东西,喜欢在直观上看到动手后的结果,才会有继续下去的兴趣。 如果你想提升自己的编程技术却苦于不知道该从何开始、没有学习的方向跟路径,那就来加入我们一起学习吧。 C/C++Linux服务器开发/后台架构师【零声学院】-学习视频教程-腾讯课堂​ke.qq.com 前言: Golang 调用 C/C++ 的教程网上很多,就我目前所看到的,个人见解就是比较乱,坑也很多。希望本文能在一定程度上,做到更通俗明了。 下面 golang 简称 go , 一如既往,少说废话,我们现在开始。

linuxguitu的博客 1368

golang与C互相调用示例

以下示例使用的操作系统都是linux,windows比较麻烦。 一、c语言调用golang库 1.main.go package main import "C" func main() {} //export Hello func Hello() string { return "Hello" } //export Test func Test() { pr...

闲人的专栏 2718

c/c++ 调用golang 方法

添加这条注释的原因:在编译动态库的时候,需要添加export funxxxx,才会生成对应的头文件。3.func main() {} 需要加入main, go语言问题,没有会编译报错。查看CC 和 CXX的值,根据自己电脑环境设置c/c++ 编译器路径。1.需要引入 import “C”通过go env 查看当前环境变量。

weixin_45893253的博客 434

【OpenIM原创】uni-app使用之 初始化会话 消息 好友 监听器

写在前面 Open-IM是由前微信技术专家打造的开源的即时通讯组件。Open-IM包括IM服务端和客户端SDK,实现了高性能、轻量级、易扩展等重要特性。开发者通过集成Open-IM组件,并私有化部署服务端,可以将即时通讯、实时网络能力快速集成到自身应用中,并确保业务数据的安全性和私密性。 了解更多原创文章: 【OpenIM原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型 【OpenIM原创】C/C++调用golang函数,golang回调C/C++函数 【OpenIM原创】简单轻松入门 一文

OpenIM的博客 1810

现代IM架构研究笔记(一):瓜子IM和OpenIM

传统架构 传统的架构(十万级用户量)还是基于多进程思想,这里以TeamTalk为例,TeamTalk是蘑菇街5年前(2015年)开源的内部企业通讯软件,当时还火爆了一下,很多人纷纷研究,各种分析文章满天飞。它的架构如图所示: 简单介绍一下工作原理: login:客户端先通过http发到login(这里应该叫rebanlancer,负载均衡),获取一个低负载(登录用户数量,即tcp连接数)的msg IP地址 msg:然后通过tcp连接msg,进行登录认证、查询会话、收发消息等。msg在整个架构

a6636656的博客 2275
上一篇: 详解微信异步队列 MQ 2.0 的功能优化及拓展思路
下一篇: 微信后台基于时间序的海量数据冷热分级架构设计实践
OpenIM
博客等级 码龄5年 295粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值