首页 > 系统相关 >golang进程通过共享内存和C++进程进行通信

golang进程通过共享内存和C++进程进行通信

时间:2024-05-13 18:08:28浏览次数:25  
标签:SHM 共享内存 C++ ptr golang 进程 include shm SIZE

目录


server

C++ 可以使用 POSIX 共享内存 API 来创建和管理共享内存
server.cpp

#include <fcntl.h>  
#include <sys/mman.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <cstring>  
#include <iostream>  
  
const char* SHM_NAME = "/my_shared_memory";  
const size_t SHM_SIZE = 4096; // 假设大小为4KB  
  
int main() {  
    int shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);  
    if (shm_fd == -1) {  
        perror("shm_open");  
        return 1;  
    }  
  
    if (ftruncate(shm_fd, SHM_SIZE) == -1) {  
        perror("ftruncate");  
        return 1;  
    }  
  
    void* ptr = mmap(nullptr, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);  
    if (ptr == MAP_FAILED) {  
        perror("mmap");  
        return 1;  
    }  
  
    // 写入数据到共享内存  
    std::strcpy(static_cast<char*>(ptr), "Hello from C++!");  
  
    // ... 等待Go客户端读取数据,或者你可以使用某种同步机制(如信号量或条件变量)  
    sleep(10);

    std::cout << "Server Received:" << static_cast<char*>(ptr) << std::endl;
  
    // 清理  
    munmap(ptr, SHM_SIZE);  
    close(shm_fd);  
    shm_unlink(SHM_NAME);  
  
    return 0;  
}

client

在Go中,你可以使用CGO来调用C语言的库

C 桥接代码 shm_bridge.c

#include <fcntl.h>  
#include <sys/mman.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <stdlib.h>  

#define SHM_NAME "/my_shared_memory"  
#define SHM_SIZE 4096  
  
void* mmap_shm() {  
    int shm_fd = shm_open(SHM_NAME, O_RDWR, 0666);  
    if (shm_fd == -1) {  
        perror("shm_open");  
        exit(1);  
    }  
  
    void* ptr = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);  
    if (ptr == MAP_FAILED) {  
        perror("mmap");  
        exit(1);  
    }  
  
    return ptr;  
}

void write_to_shared_memory(void* shm, char* data, size_t len) {  
    memcpy(shm, data, len);  
}

/*

    https://static.kancloud.cn/idzqj/customer/2128198

    func C.CString(string) *C.char              // go字符串转化为char*
    func C.CBytes([]byte) unsafe.Pointer        // go 切片转化为指针
    func C.GoString(*C.char) string             // C字符串 转化为 go字符串
    func C.GoStringN(*C.char, C.int) string     
    func C.GoBytes(unsafe.Pointer, C.int) []byte

*/

client.go

package main

/*
#cgo CFLAGS: -std=c99
#cgo LDFLAGS: -lrt
#include "shm_bridge.c"
*/
import "C"
import (
	"fmt"
)

func main() {
	ptr := C.mmap_shm()
	defer C.munmap(ptr, C.SHM_SIZE) // 注意:这只是一个示例,实际的munmap调用可能需要更复杂的处理

	// 读取共享内存中的数据
	data := C.GoStringN((*C.char)(ptr), C.SHM_SIZE)
	fmt.Println(data) // 输出: Hello from C++!

	// 要写入的字符串
	str := "Hello from Go!\x00"

	// 调用C函数将数据写入共享内存
	// 注意:我们传递data的首地址和长度给C函数
	C.write_to_shared_memory(ptr, C.CString(str), C.size_t(len(str)))
}

标签:SHM,共享内存,C++,ptr,golang,进程,include,shm,SIZE
From: https://www.cnblogs.com/yubo-guan/p/18189736

相关文章

  • c++ union
    在C++中,`union`是一种特殊的数据结构,它允许在同一内存空间中存储不同类型的数据。`union`允许您定义一个变量,但这个变量可以存储多种不同类型的值,而不是只能存储一种类型的值。在任何给定时间,`union`中只有一个成员可以有值,所有其他成员都将保持未定义的状态。`union`的声......
  • c++ true_type与false_type
    std::true_type和std::false_type实际上是类型别名是两个类型(类模板)注意区分true_type与false_type与true和false区别true_type,false_type代表类型true,false代表值nmsp1::FalseTypemyfunc1();//返回假这种含义nmsp1::TrueTypemyfunc2();//返回真这种含......
  • c++-----declval
    std::declval基本概念和常规实例std::decval–C++新标准中出现的函数模板,没有函数体(只有声明、没有实现),无法调用,一般用于与decltype,sizeof等关键字配合来进行类型推导、占用内存空间计算等查看源码: add_rvalue_reference:是C++标准库中的类模板,他的能力是给进一个类型,它......
  • linux批量杀死多个进程
    ps-ef|grep"tomcat"|grep-vgrep|awk'{print$2}'|xargskill-9“ps-ef”是linux里查看所有进程的命令。这时检索出的进程将作为下一条命令“greptomcat”的输入。“greptomcat”的输出结果是,所有含有关键字“tomcat”的进程。“grep-vgrep”是在列出的......
  • golang 压缩包解压问题汇总
    解压代码packagemainimport( "archive/zip" "bytes" "fmt" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" "io" "io/ioutil" "os" "path/......
  • C++:private继承
    平时我们使用类继承是这个画风:classchild:public::father{};表示子类child继承父类father,这里有个关键词"public",表示继承到的父类属性和方法为自己的public成员,这种情况下子类的对象或者说实例化是可以直接访问这些成员的 当改成classchild:private::father{};则......
  • c++踩方格-动态规划基础题
    有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:a、每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;b、走过的格子立即塌陷无法再走第二次;c、只能向北、东、西三个方向走;请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同......
  • C++类型转换
    一、整形提升整型提升是一种隐式类型转换,当涉及到小于int类型的整数(如char、short、bool等)时。整型提升的目的是确保所有的操作数在算术运算或比较操作中具有相同的类型,通常是int类型,如果int不能表示该值,则可能会提升到unsignedint或更大的整数类型。二、无符号数和带符号数进......
  • Effective C++:2.构造、析构、赋值函数
    几乎每个class都会有一个或者多个构造函数,一个析构函数,一个copyassignment函数,因此有必要加深理解1.条款05:了解C++默默编写并调用哪些函数如果你没有生成一下函数,那么C++会在需要的时候(被调用)帮你自动生成这些函数:default构造函数copy构造函数default析构函数copyassign......
  • 编程竞赛中 C/C++ I/O 的使用
    C的字符串读取scanf以空行为分割进行读取数据。get和fgets以\n为分割读取数据。读取输入直到遇到\n或\0才终止。C++读取字符串cin以空格为分割读取数据。getline默认以换行符为分割读取数据。在使用getline时,要注意处理多个\n连到一块的情况。当读取77\n\n77时,......