Linux下GO语言内存共享,CGO实现

fyxichen · · 1670 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

package ce

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
)

/*
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <string.h>

int Size;
int Shm_id;
key_t Key;
char *Shm_add;
int getMem(char *pathname,int size)
{
    Key = ftok((char *)pathname,0x03);
    if(Key==-1)
    {
        return -1;
    }
    Shm_id=shmget(Key,size,IPC_CREAT|IPC_EXCL|0600);
    if (Shm_id==-1)
    {
        return -2;
    }
    Shm_add=shmat(Shm_id,0,0);
    if (Shm_add==(void *)-1)
    {
	    return -3;
    }
    Size=size;
    return 0;
}
int close()
{
    int result;
    result=shmdt(Shm_add);
    if (result != 0)
    {
        return result;
    }
    result=shmctl(Shm_id, IPC_RMID, NULL);
    if (result != 0)
    {
        return result;
    }
    return 0;
}
int write(char *str)
{
        int len;
	len=strlen(str);
	if (len >= Size)
	{
		return 0;
	}
	strcpy((char *)Shm_add,(char *)str);
	return len;
}
char* read()
{
	return (char *)Shm_add;
}
*/
import "C"

type Mem struct {
	Shm_id C.int
	size   int
}

func GetShareMem(path string, size int) (*Mem, error) {
	info, err := os.Lstat(path)
	if err != nil {
		return nil, err
	}
	if info.IsDir() {
		return nil, errors.New("Must Is File")
	}
	cstr := C.CString(path)
        num := C.getMem(cstr, C.int(size))
        C.free(unsafe.Pointer(cstr))
	switch num {
	case 0:
		return &Mem{C.Shm_id, size}, nil
	case -1:
		return nil, errors.New("Get Key error")
	case -2:
		return nil, errors.New("Get Shm_id error")
	case -3:
		C.close()
		return nil, errors.New("Map AddrSpace error")
	}
	C.close()
	return nil, errors.New("Unknow error")
}

func (self *Mem) Close() error {
	num := C.close()
 	if num != 0 {
		cmd := exec.Command("ipcrm", "-m", fmt.Sprint(self.Shm_id))
		return cmd.Run()
	}
	return nil
}
func (self *Mem) Read() string {
	return C.GoString(C.read())
}
func (self *Mem) Write(body string) C.int {
    if len(body) > self.size {
        return C.int(0)
    }
    return C.write(C.CString(body))
}


package main

import (
	"flag"
	"fmt"
)

/*
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
char* GetMem(int Shm_id)
{
    char *Shm_add;
    Shm_add=shmat(Shm_id,0,0);
    if (Shm_add==(void *)-1)
    {
        return (char *)-1;
    }
    return (char *)Shm_add;
}
int close(char *Shm_add)
{
	int result;
	result=shmdt(Shm_add);
    if (result != 0)
    {
        return result;
    }
}
*/
import "C"

type ShareMem struct {
	Addr *C.char
}

func main() {
	i := flag.Int("m", 0, "-m=12345")
	flag.Parse()
	x := GetShareMem(*i)
	if x == nil {
		fmt.Println("open error")
	}
	defer x.Close()
	fmt.Println(x.Read())
}

func GetShareMem(shm_id int) *ShareMem {
	m,err := C.GetMem(C.int(shm_id))
	if err != nil {
		return nil
	}
	return &ShareMem{m}
}

func (self *ShareMem) Close() {
	C.close(self.Addr)
}

func (self *ShareMem) Read() string {
	return C.GoString(self.Addr)
}

package main
import (
    "fmt"
    "ce"
)
func main() {
	m, err := ce.GetShareMem("/tmp/.tmpfile", 1024)
	if err != nil {
		fmt.Println(err)
	}
	defer m.Close()
	m.Write("fyxichen")
	fmt.Println(m.Read())
}



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:fyxichen

查看原文:Linux下GO语言内存共享,CGO实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1670 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传