heiher / natmap

TCP/UDP port mapping for full cone NAT
MIT License
1.38k stars 103 forks source link

编译成静态链接报错 #67

Closed QZAiXH closed 5 months ago

QZAiXH commented 5 months ago

首先要声明一下,我对C并不熟悉。我现在希望将这个项目整合到go项目中运行,通过cgo来调用其中的C函数。现在遇到的问题是在编译go项目时,需要先将相关代码编译成静态库或动态库。根据文档上所述,执行命令 make ENABLE_STATIC=1 就可以了。但是,在我执行这个命令后报错:

src/hev-misc.h:13:10: fatal error: hev-task.h: No such file or directory
   13 | #include <hev-task.h>
      |          ^~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:74: build/hev-conf.o] Error 1

请问我是哪个步骤出错了?

heiher commented 5 months ago

明白你的意思。编译报错应该是由于没有拉取submodule,git clone需要带--recursive参数。目前没有支持作为库调用,只能编译为可执行程序运行,ENABLE_STATIC=1是静态链接成可执行文件。

QZAiXH commented 5 months ago

谢谢你的指导,目前我初步尝试了下,似乎能正常运行。代码如下:

package main

/*
#cgo CFLAGS: -I../third-part/hev-task-system/include -I../third-part/hev-task-system/src/lib/rbtree
#cgo LDFLAGS: -L../third-part/hev-task-system/bin -lhev-task-system -lpthread

#include <stdlib.h>
#include "hev-main.h"
*/
import "C"
import (
    "fmt"
    "unsafe"
)

func main() {
    // 参数数组
    args := []string{"natmap", "-s", "turn.cloudflare.com", "-h", "qq.com", "-b", "8081"}

    // 创建C风格的参数数组
    argc := C.int(len(args))
    argv := make([]*C.char, len(args))
    for i, arg := range args {
        argv[i] = C.CString(arg)
        defer C.free(unsafe.Pointer(argv[i])) // 确保在函数结束时释放内存
    }

    // 调用C函数
    ret := C.hev_main(argc, &argv[0])
    if ret == 0 {
        fmt.Println("调用C函数成功")
    } else {
        fmt.Println("调用C函数失败")
    }
}

我修改了hev-main.h里的函数名,不然编译会报错说有两个main函数。

这个main.go文件需要放到src目录。

编译出来后的可执行文件运行返回如下输出 image

这是执行正常吗?

heiher commented 5 months ago

可以的,执行正常。

QZAiXH commented 5 months ago

太棒了,我将尝试测试是否有bug,如果没有问题将尝试提交个pr让这个库能直接被go当作第三方库调用