使用CGO从C源代码构建包含C函数的Golang共享库

使用CGO从C源代码构建包含C函数的Golang共享库 大家好…

我想构建一个Go的C共享库,其中包含来自C源代码的C函数…cgo能实现这个功能吗?

谢谢

3 回复
感谢jayts...
情况是这样的:
我能够从C语言访问Go编写的库,反之亦然。但我想做的是用Go语言构建一个C共享库(使用-buildmode=c-shared)...问题在于,我的Go源代码中使用了来自C应用程序(即主应用程序)的C函数。

关键在于,我的C应用程序中有"main"函数需要导出到Go源代码中,同时我需要将Go源代码编译成C共享库(*.so),并在我的C应用程序中使用它,而该C应用程序又将C函数导出给了Go。我能否实现这样的架构?

之所以想构建这样的应用程序,是因为我希望其他人能够使用Go语言而非C语言来参与贡献。

更多关于使用CGO从C源代码构建包含C函数的Golang共享库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


(我不确定是否理解了这个问题,假设您想要使用cgo来访问用C语言编写的库。)

请参阅第二个代码示例中关于cgo的文档

https://golang.org/cmd/cgo/

具体来说:

// #cgo CFLAGS: -DPNG_DEBUG=1
// #cgo amd64 386 CFLAGS: -DX86=1
// #cgo LDFLAGS: -lpng
// #include <png.h>
import "C"

这展示了如何在构建过程中通过指定LDFLAGS来包含C语言库。

是的,使用CGO可以从C源代码构建包含C函数的Golang共享库。以下是实现步骤和示例代码:

首先,创建C头文件 clib.h

#ifndef CLIB_H
#define CLIB_H

int add(int a, int b);
void print_message(const char* msg);

#endif

创建对应的C源文件 clib.c

#include <stdio.h>
#include "clib.h"

int add(int a, int b) {
    return a + b;
}

void print_message(const char* msg) {
    printf("Message: %s\n", msg);
}

创建Go包装文件 wrapper.go

package main

/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lclib

#include "clib.h"
*/
import "C"
import "unsafe"

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

//export PrintMessage
func PrintMessage(msg string) {
    cmsg := C.CString(msg)
    defer C.free(unsafe.Pointer(cmsg))
    C.print_message(cmsg)
}

func main() {}

构建共享库:

# 首先构建C静态库
gcc -c clib.c -o clib.o
ar rcs libclib.a clib.o

# 然后构建Go共享库
go build -buildmode=c-shared -o libgoshared.so wrapper.go

使用示例(C语言调用):

#include <stdio.h>
#include "libgoshared.h"

int main() {
    int result = Add(5, 3);
    printf("5 + 3 = %d\n", result);
    
    PrintMessage("Hello from C!");
    return 0;
}

编译并运行C程序:

gcc -o test test.c -L. -lgoshared
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./test

关键点说明:

  1. Go文件必须包含 //export 指令导出函数
  2. 使用 -buildmode=c-shared 标志构建共享库
  3. CGO会自动生成头文件 libgoshared.h
  4. 需要正确处理C字符串的内存管理

这样就能创建包含C函数的Golang共享库,供其他语言调用。

回到顶部