Cgo可以在另一个目录中调用C函数吗?

时间:2016-06-18 10:10:43

标签: c go cgo

似乎我无法使用Cgo来调用在另一个目录中声明的C函数,而不是当前的Go包。

所有文件的代码:

// TestGoCallOC.go
package main
/*
#include "test.h"
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation
*/
import "C"
import (
    "fmt"
)
func main()  {
    fmt.Println(C.fortytwo())
}

// test.h
#include <stdio.h>
#include <stdlib.h>
int fortytwo();

// test.m
#include "test.h"
int fortytwo() {
    return 42;
}

如果我将所有文件放在一个目录中:

|--src
   |--TestGoCallOC
      |--TestGoCallOC.go
      |--test.h
      |--test.m

并运行Go main函数,可以调用这两个C函数。

但是如果我把C文件(实际上它们是Objective-C文件)放在另一个目录中:

|--src
   |--TestGoCallOC
      |--TestGoCallOC.go
   |--SomeOCCodes
      |--test.h
      |--test.m

,将前导码中#include "test.h"的文件路径更改为绝对路径,并运行Go main函数,无法调用这两个C函数。

错误讯息是

架构x86_64的未定义符号:   &#34; _fortytwo&#34;,引自:       TestGoCallOC.cgo2.o中__cgo_b3674ecbf56b_Cfunc_fortytwo      (也许你的意思是:__ cgo_b3674ecbf56b_Cfunc_fortytwo) ld:找不到架构x86_64的符号 clang:错误:链接器命令失败,退出代码为1(使用-v查看调用) 退出状态2

我做错了什么吗?或者Cgo无法做到这一点?

1 个答案:

答案 0 :(得分:2)

根据https://golang.org/cmd/cgo/
包中的所有cgo CPPFLAGS和CFLAGS指令都连接在一起并用于编译该包中的C文件。程序包中的所有CPPFLAGS和CXXFLAGS指令都连接在一起,用于编译该程序包中的C ++文件。程序中任何包中的所有LDFLAGS指令都被连接并在链接时使用。所有pkg-config指令都连接在一起并同时发送到pkg-config,以添加到每组适当的命令行标志。

Go package boundary是src文件夹,因此您可以将所有c文件放在同一个文件夹中,或使用包含C文件(非h文件)解决方法,如下所示:

// main.go
package main

//#include "../ctest/test.c"
import "C"
import "fmt"

func main() {
    r := C.Add(10, 20)
    fmt.Println(r)
}
ctest目录中的

和c文件:

//test.c

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

这很好用。