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

3

看起来我不能使用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主函数时,这两个C函数可以被调用。

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

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

请将头文件#include "test.h"的文件路径更改为其绝对路径,并运行Go主函数,否则这两个C函数将无法调用。

错误信息如下:

Undefined symbols for architecture x86_64: "_fortytwo", referenced from: __cgo_b3674ecbf56b_Cfunc_fortytwo in TestGoCallOC.cgo2.o (maybe you meant: __cgo_b3674ecbf56b_Cfunc_fortytwo) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) exit status 2

我做错了什么吗?或者Cgo不能做到这一点吗?

1个回答

4

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

Go包边界是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;
}

这个可以正常工作。

非常感谢。我尝试了#include "../../test.m",然后我可以调用这些C函数。但为什么#include头文件不起作用? - Buqian Zheng
源文件包含:当预处理器找到一个#include指令时,它会用指定文件的全部内容替换它。 - user6169399

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接