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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值