Cgo 可以调用在另一个目录中声明的 C 函数吗?
Can Cgo call C function declared in another directory?
似乎我不能使用 Cgo 调用在另一个目录而不是当前 Go 包中声明的 C 函数。
所有文件的代码:
// 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:
“_fortytwo”,引用自:
__cgo_b3674ecbf56b_Cfunc_fortytwo 在 TestGoCallOC 中。cgo2.o
(也许你的意思是:__cgo_b3674ecbf56b_Cfunc_fortytwo)
ld:未找到体系结构的符号 x86_64
clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
退出状态 2
我是不是做错了什么?还是Cgo做不到?
根据https://golang.org/cmd/cgo/
一个包中的所有 cgo CPPFLAGS 和 CFLAGS 指令被连接起来并用于编译该包中的 C 文件。一个包中的所有 CPPFLAGS 和 CXXFLAGS 指令都被连接起来并用于编译该包中的 C++ 文件。程序中任何包中的所有 LDFLAGS 指令都被连接起来并在 link 次使用。所有 pkg-config 指令都被连接起来并同时发送到 pkg-config 以添加到每组适当的命令行标志中。
Go 包边界是 src 文件夹,因此您可以将所有 c 文件放在同一文件夹/或使用 include 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;
}
这很好用。
似乎我不能使用 Cgo 调用在另一个目录而不是当前 Go 包中声明的 C 函数。
所有文件的代码:
// 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: “_fortytwo”,引用自: __cgo_b3674ecbf56b_Cfunc_fortytwo 在 TestGoCallOC 中。cgo2.o (也许你的意思是:__cgo_b3674ecbf56b_Cfunc_fortytwo) ld:未找到体系结构的符号 x86_64 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) 退出状态 2
我是不是做错了什么?还是Cgo做不到?
根据https://golang.org/cmd/cgo/
一个包中的所有 cgo CPPFLAGS 和 CFLAGS 指令被连接起来并用于编译该包中的 C 文件。一个包中的所有 CPPFLAGS 和 CXXFLAGS 指令都被连接起来并用于编译该包中的 C++ 文件。程序中任何包中的所有 LDFLAGS 指令都被连接起来并在 link 次使用。所有 pkg-config 指令都被连接起来并同时发送到 pkg-config 以添加到每组适当的命令行标志中。
Go 包边界是 src 文件夹,因此您可以将所有 c 文件放在同一文件夹/或使用 include 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;
}
这很好用。