Golang中如何与他人共享代码

Golang中如何与他人共享代码 我们有一些Go语言代码。这些代码是我们的业务逻辑。

我们希望与其他公司共享,但我们希望以动态链接库(.dll)或共享对象文件(.so)的形式共享,而不是直接共享源代码。

它应该像为他们提供的SDK一样工作。

10 回复

这确实是该语言的一个缺点。这在所有语言中都很常见。

更多关于Golang中如何与他人共享代码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


混淆处理在分发整个应用程序时是有效的。但这里的问题是要提供包,但不展示代码。

不知道你在说什么,相反,只有少数几种语言可以这样使用。大部分语言都没有这种功能,而且我认为 Golang 决定放弃支持它是有充分理由的。

一个可行的方案是构建一个可执行的 .exe 文件,将其保存在您的 Google Drive、Microsoft OneDrive 或 Amazon AWS 上,然后与您的业务伙伴共享。

谢谢。

微服务是一种选择。在我的应用中,我有大量的数据库事务。我不知道如何用微服务来管理事务。

如何对 Go 代码进行混淆。

如果你知道,请指导一下。

你可能想看看 GitHub - burrowers/garble: Obfuscate Go builds。我自己没有使用它的经验,但我相信 wails 使用了它。

这通常是不可行的。聪明的人可以逆向工程一切,这只是投入多少精力的问题。即使你技术上能够提供一个独立的二进制文件。

我想到两个选项。 1. 微服务2. 混淆。我的意思是,为什么不呢? :partying_face:

没有好的方法来实现这一点。binary-only-package 的支持在 go1.12 之后就被移除了。关于此问题曾有过大量的讨论。你可以尝试使用插件,但它的选项非常有限,看起来也不够优雅,在 Windows 上无法工作,并且编译时需要 cgo。另一方面,你也可以尝试在严格的许可协议下分享你的源代码。

在Go语言中,可以通过构建C共享库的方式将代码编译为动态链接库(.dll、.so或.dylib),供其他语言调用。以下是具体步骤和示例:

1. 编写导出函数的Go代码

使用//export注释标记需要导出的函数,并导入C包。

// sdk.go
package main

import "C"
import "fmt"

//export Hello
func Hello(name *C.char) *C.char {
    msg := fmt.Sprintf("Hello, %s!", C.GoString(name))
    return C.CString(msg)
}

//export Add
func Add(a, b C.int) C.int {
    return a + b
}

func main() {
    // 必须存在main函数,但不会被执行
}

2. 构建共享库

根据目标平台使用-buildmode=c-shared参数编译:

# Linux/macOS
go build -buildmode=c-shared -o libsdk.so sdk.go

# Windows
go build -buildmode=c-shared -o sdk.dll sdk.go

3. 生成的头文件

构建后会同时生成头文件(如libsdk.h),其中包含函数声明:

/* libsdk.h */
extern char* Hello(char* name);
extern int Add(int a, int b);

4. 其他语言调用示例

C语言调用示例:

// client.c
#include <stdio.h>
#include "libsdk.h"

int main() {
    char* msg = Hello("World");
    printf("%s\n", msg);
    
    int sum = Add(10, 20);
    printf("Sum: %d\n", sum);
    
    free(msg); // 释放Go返回的字符串内存
    return 0;
}

编译并链接:

# Linux
gcc -o client client.c -L. -lsdk

# Windows (MinGW)
gcc -o client.exe client.c -L. -lsdk

Python调用示例(使用ctypes):

# client.py
from ctypes import CDLL, c_char_p, c_int

lib = CDLL('./libsdk.so')  # Linux/macOS
# lib = CDLL('sdk.dll')    # Windows

lib.Hello.argtypes = [c_char_p]
lib.Hello.restype = c_char_p

lib.Add.argtypes = [c_int, c_int]
lib.Add.restype = c_int

msg = lib.Hello(b"Python")
print(msg.decode('utf-8'))

sum = lib.Add(10, 20)
print(f"Sum: {sum}")

5. 内存管理注意事项

  • Go返回的字符串需要调用free()释放(C语言)或由ctypes自动处理(Python)
  • 复杂数据结构可通过JSON字符串传递

6. 跨平台构建

使用环境变量指定目标平台:

# 构建Windows DLL
GOOS=windows GOARCH=amd64 go build -buildmode=c-shared -o sdk.dll sdk.go

# 构建Linux SO
GOOS=linux GOARCH=amd64 go build -buildmode=c-shared -o libsdk.so sdk.go

# 构建macOS Dylib
GOOS=darwin GOARCH=amd64 go build -buildmode=c-shared -o libsdk.dylib sdk.go

7. 完整项目结构示例

sdk-project/
├── go.mod
├── sdk.go          # 导出函数实现
├── build.sh        # 构建脚本
├── examples/
│   ├── c/          # C语言示例
│   ├── python/     # Python示例
│   └── java/       # JNI示例
└── README.md       # 使用文档

这种方法可以将Go业务逻辑封装为二进制SDK,保护源代码的同时提供跨语言调用能力。

回到顶部