Golang如何不暴露源代码将包作为库导出

Golang如何不暴露源代码将包作为库导出 我一直在尝试寻找一种方法,能够向客户端(另一个Go项目)暴露某些框架包,同时不暴露源代码。具体调用框架的哪些方法,则由客户端根据需求自行决定。

使用 Buildmode=archive

使用 Buildmode=shared

  • 思路是创建一个动态链接库,以便在运行时访问库中的代码元素。这需要使用 -linkshared-buildmode=shared 标志。 来源Shared library in Go? - Stack Overflow 问题-buildmode=shared 本身存在一系列问题,当我们尝试使用 -linkshared 构建时,会抛出运行时错误。曾有提案建议完全移除 -buildmode=shared

使用 Buildmode=plugin

  • 思路是为主包创建一个插件,并按需加载其中的函数/变量。 问题:客户端需要编写更多代码来访问插件中的函数/变量。

遗憾的是,这些方法都不适用于我的用例。如果还有其他方法可以实现这个目标,请在评论中提出建议。另外,我对Go语言还比较陌生,如果我理解有误,请随时指正。

提前感谢。


更多关于Golang如何不暴露源代码将包作为库导出的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

插件部分的源代码:https://technobeans.com/2019/03/05/plugins-in-go/ 提议移除 -buildmode=shared 的讨论:https://github.com/golang/go/issues/47788

更多关于Golang如何不暴露源代码将包作为库导出的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在 Go 中,确实没有完美的方法可以完全隐藏源代码。不过,根据你的需求,以下是一些可行的方案:

1. 使用 internal 目录

将不希望暴露的代码放在 internal 目录下。Go 的工具链会阻止外部包导入 internal 目录下的包。这是 Go 官方推荐的封装方式。

示例结构:

myproject/
├── go.mod
├── public/
│   ├── go.mod
│   └── public.go
└── internal/
    └── internal.go

internal/internal.go:

package internal

func Secret() string {
    return "隐藏的实现"
}

public/public.go:

package public

import "myproject/internal"

func PublicAPI() string {
    return internal.Secret()
}

外部项目只能导入 myproject/public,无法直接访问 internal 包。

2. 使用接口进行抽象

通过接口暴露功能,将具体实现隐藏在返回接口的函数后面。

示例:

package mylib

type MyInterface interface {
    DoSomething() string
}

type hiddenImpl struct{}

func (h hiddenImpl) DoSomething() string {
    return "具体实现"
}

func New() MyInterface {
    return hiddenImpl{}
}

客户端代码:

package main

import "mylib"

func main() {
    obj := mylib.New()
    result := obj.DoSomething()
    println(result)
}

3. 编译为 C 共享库

使用 cgo-buildmode=c-shared 将 Go 代码编译为 C 共享库。

示例:

package main

import "C"

//export MyFunction
func MyFunction() *C.char {
    return C.CString("来自 Go 库的结果")
}

func main() {}

编译命令:

go build -buildmode=c-shared -o mylib.so mylib.go

客户端通过 C 接口调用,无法看到 Go 源代码。

4. 使用 gRPC 或 HTTP API

将框架作为服务运行,通过 gRPC 或 HTTP API 暴露功能。客户端通过网络调用,完全看不到源代码。

gRPC 示例:

// 服务端
package main

import (
    "context"
    "net"

    "google.golang.org/grpc"
    pb "path/to/your/proto"
)

type server struct {
    pb.UnimplementedMyServiceServer
}

func (s *server) MyMethod(ctx context.Context, req *pb.MyRequest) (*pb.MyResponse, error) {
    return &pb.MyResponse{Result: "处理结果"}, nil
}

func main() {
    lis, _ := net.Listen("tcp", ":50051")
    s := grpc.NewServer()
    pb.RegisterMyServiceServer(s, &server{})
    s.Serve(lis)
}

5. 代码混淆工具

使用第三方工具如 garble 对代码进行混淆,增加逆向工程难度。

安装和使用:

go install mvdan.cc/garble@latest
garble build -o myapp mypackage

这些方法各有优缺点,需要根据具体场景选择。internal 目录和接口抽象是最常用的方式,既能保持 Go 的简洁性,又能实现良好的封装。

回到顶部