文档章节

导出私有函数与私有变量

x
 xtof
发布于 11/15 20:07
字数 770
阅读 6
收藏 0

在Go语言中, package中包含函数与变量通过identifier的首字母是否大写来决定它是否可以被其它package所访问。当一个函数或变量名称为小写字母时,默认是无法被其他package引用的. 
有没有办法突破这个限制呢? 
实际上在go官方文档中已有说明, 这需要用到一个编译器指令 

//go:linkname localname importpath.name 

官方的解释是: 

The //go:linkname directive instructs the compiler to use “importpath.name” as the object file symbol name for the variable or function declared as “localname” in the source code. Because this directive can subvert the type system and package modularity, it is only enabled in files that have imported "unsafe". 

//go:linkname指令指示编译器使用importpath.name作为源代码中声明为localname的变量或函数的对象文件符号名。因为这个指令可以破坏类型系统和包的模块化,所以它只在导入“不安全”的文件中启用。

我的理解就是使用localname作为当前package本地函数或变量名称,关联到importpath.name实际的符号引用.实际上locaname只是一个作为链接符号,这个跟WINDOWS中的DLL符号关联有点类似.

示例
以下示例引用了runtime.sysMmap一系列私有函数与变量,用于创建一个huagepage共享内存区域
 

package main


/*
#cgo CFLAGS:
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <sys/ucontext.h>
#include <sys/unistd.h>
#include <errno.h>
#include <signal.h>
*/
import "C"

import (
    "fmt"
    "os"
    "encoding/hex"
    "syscall"
    "reflect"
    _ "runtime"
    "unsafe"
    "os/exec"
)

const (
    PROT_NONE  = C.PROT_NONE
    PROT_READ  = C.PROT_READ
    PROT_WRITE = C.PROT_WRITE
    PROT_EXEC  = C.PROT_EXEC

    MAP_SHARED  = 0x1
    MAP_ANON    = C.MAP_ANONYMOUS
    MAP_PRIVATE = C.MAP_PRIVATE
    MAP_FIXED   = C.MAP_FIXED
)


//go:linkname physPageSize runtime.physPageSize
//go:linkname callCgoMmap runtime.callCgoMmap
//go:linkname callCgoMunmap runtime.callCgoMunmap
//go:linkname sysMmap runtime.sysMmap
//go:linkname sysMunmap runtime.sysMunmap
//go:linkname Mmap runtime.mmap
//go:linkname Munmap runtime.munmap

// sysMmap calls the mmap system call. It is implemented in assembly.
func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)

// callCgoMmap calls the mmap function in the runtime/cgo package
// using the GCC calling convention. It is implemented in assembly.
func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) uintptr

// sysMunmap calls the munmap system call. It is implemented in assembly.
func sysMunmap(addr unsafe.Pointer, n uintptr)

// callCgoMunmap calls the munmap function in the runtime/cgo package
// using the GCC calling convention. It is implemented in assembly.
func callCgoMunmap(addr unsafe.Pointer, n uintptr)

func Mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
func Munmap(addr unsafe.Pointer, n uintptr)

var physPageSize uintptr
const (
    ENOMEM = 12
)
func GetPhysPageSize() uintptr {
    return physPageSize
}

func TestHugePage() {
    file := "/dev/hugepages/hp"
    f, err := os.OpenFile(file, os.O_CREATE|os.O_RDWR, 0644)
    if err != nil {
        fmt.Printf("Open: %v", err)
        return
    }
    var length uintptr = 2 * 1024 * 1024;
    var flags int32 = MAP_SHARED;
    var proto int32 = PROT_READ|PROT_WRITE;
    addr, e := sysMmap(nil, length, proto, flags, int32(f.Fd()), 0)
    if e != 0 {
        fmt.Printf("Mmap occur error %d\n", e);
        return
    }
    fmt.Printf("Mmap %p\n", addr);

    var x reflect.SliceHeader
    x.Len = 512
    x.Cap = 512
    x.Data = uintptr(addr)
    var payload []byte = *(*[]byte)(unsafe.Pointer(&x))

    stdoutDumper := hex.Dumper(os.Stdout)
    defer stdoutDumper.Close()
    stdoutDumper.Write(payload)

    // Munmap(addr, length)
}
func main() {
    var pid int
    pid = syscall.Getpid()
    fmt.Println("GetPhysPageSize:", GetPhysPageSize())
    TestHugePage()
    cmd := exec.Command("cat", str)
    out, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Printf("cmd.Run() failed with %s\n", err)
        return
    }
    fmt.Printf("combined out:\n%s\n", string(out))
}

 

© 著作权归作者所有

共有 人打赏支持
x
粉丝 0
博文 121
码字总数 174316
作品 0
深圳
私信 提问

暂无文章

正则表达式匹配不包含

^((?!xxx).)*$

安小乐
8分钟前
1
0
python Windows tkinter应用开发3 列出目录的所有文件

在本章中,我们将编写程序来执行此操作。 1)选择文件夹。 2)在UI的标签部分打印该文件夹中的所有文件名(带文件扩展名)。 首先,修改selectFile函数以打开文件夹。主文件如下: from tki...

python测试开发人工智能安全
9分钟前
1
0
使用Laya引擎开发微信小游戏(上)

  使用一个简单的游戏开发示例,由浅入深,介绍了如何用Laya引擎开发微信小游戏。      img      作者:马晓东,腾讯前端高级工程师。      微信小游戏的推出也快一年时间了,...

SEOwhywhy
14分钟前
1
0
react程序开发问题记录

1、webpack.config.dev.js文件的publicpath配置

teamlog
26分钟前
2
0
javascript 值转换为布尔值

任意javascript 的值都可以转换为布尔值。 特别是在 if() 等判断中使用的时候: 下面这些值会被转换为 false undefined , null , 0 , -0 , NaN , "" 空字符串 来自 JavaScript 权威指南 书籍...

之渊
29分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部