linux下go和c通过共享内存进行通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/javaxflinux/article/details/82555892
  • 安装centos7

选择的版本是CentOS-7-x86_64-Minimal-1804.iso,安装完虚拟机之后,vi /etc/sysconfig/network-script/ifcfg-ens33,设置ONBOOT=yes,VM中的网络连接设置的是安装默认的NAT模式,此时在虚拟机中应该可以ping通www.baidu.com,安装ifconfig查看接口信息,使用命令yum search ifconfig进行安装包查询,使用命令yum -y install net-tools.x86_64进行安装。

  • 安装go

使用命令yum search go进行安装包查询,使用命令yum -y install golang.x86_64进行go语言安装

使用命令go env来查看go是否安装以及go的环境变量信息

vi hello.go(编辑如下源代码)

package main

import "fmt"

func main() {
   fmt.Println("Hello, World!")
}

go run hello.go(运行)

  • 代码实现

共享内存接口代码shm_mem.h

int my_shm_open(char* filename, int open_flag);
int my_shm_update(int shm_id, char* content);
int my_shm_close(int shm_id);

共享内存接口代码shm_mem.c

#include <stdlib.h> 
#include <string.h>
#include <sys/shm.h>
#include <sys/types.h>
 
int my_shm_open(char* filename, int open_flag){
    int shm_id;
    key_t key;
    key = ftok(filename, 0x03);
    if(key == -1){
        return -1;
    }
    if(open_flag)
        shm_id = shmget(key, 4096, IPC_CREAT|IPC_EXCL|0600);
    else
        shm_id = shmget(key, 0, 0);
    if(shm_id == -1){
        return -1;
    }
    return shm_id;
}
 
int my_shm_update(int shm_id, char* content){
    char* addr;
    addr = (char*)shmat(shm_id, NULL, 0);
    if(addr == (char*)-1){
        return -1;
    }
    if(strlen(content) > 4095)
        return -1;
    strcpy(addr, content);
    shmdt(addr);
    return 0;
}
 
int my_shm_close(int shm_id){
    shmctl(shm_id, IPC_RMID, NULL);
    return 0;
}
 
char* my_shm_read(char* filename){
    int shm_id;
    char* addr;
    char* s;
    shm_id = my_shm_open(filename, 0);
    if(shm_id == -1)
        return NULL;
    addr = (char*)shmat(shm_id, NULL, 0);
    if(addr == (char*)-1){
        return NULL;
    }
    s = (char*)malloc(strlen(addr) + 1);
    strcpy(s, addr);
    shmdt(addr);
    return s;
}

go语言写内容到共享内存shm.go

package main
 
//#include <stdlib.h>
//#include "shm_mem.h"
import "C"
import "unsafe"
 
import (
    "strconv"
    "fmt"
    "log"
    "time"
)
 
type errorString struct {
    s string
}
 
func (e *errorString) Error() string {
    return e.s
}
 
func open(file string) (int, error) {
    f := C.CString(file)
    defer C.free(unsafe.Pointer(f))
    r := int(C.my_shm_open(f, C.int(1)))
    if r == -1 {
        return 0, &errorString{"error"}
    }
    return r, nil
}
 
func update(shm_id int, content string) error {
    c := C.CString(content)
    defer C.free(unsafe.Pointer(c))
    r := int(C.my_shm_update(C.int(shm_id), c))
    if r == -1 {
        return &errorString{"update error"}
    }
    return nil
}
 
func close(shm_id int) error {
    C.my_shm_close(C.int(shm_id))
    return nil
}
 
func main() {
    id, err := open("./tmp")
    if err != nil {
	fmt.Println("xx");
        log.Fatal(err)
    }
    defer close(id)
    fmt.Println("yy");
    var i int = 0
    for true {
        i++ 
        fmt.Println(i);
        err = update(id, strconv.Itoa(i))
        if err != nil {
            log.Fatal(err)
        }
        time.Sleep(1e9 * 1)
    }
}

c语言从共享内存读取内容

#include <stdio.h>


int main() 
{
	char *str;

	while(1) {
		str = my_shm_read("./tmp");
		if (str == NULL) {
			printf("str is NUll.\n");
		} else {
			printf("str is %s.\n", str);
		}
		sleep(1);
	}

}

编译go:go build

编译c:gcc main.c shm_mem.c -o main

其他:运行go程序之前,touch ./tmp;另外通过ipcs -m来查看共享内存情况,通过ipcrm -m shmid(填具体值)来删除

运行截图

做此测试的出发点,是想通过go语言做web配置的控制平面,然后通过共享内存将配置下发到c来编写的数据报文处理的数据平面。

猜你喜欢

转载自blog.csdn.net/javaxflinux/article/details/82555892