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


shm_open

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)))
}

shmget

client



server


Golang直接操作共享内存

posted @ 2024-05-13 18:06  guanyubo  阅读(316)  评论(0编辑  收藏  举报