有没有办法构建一个Go + C应用程序:
一般来说,我正在试图弄清楚如何从用于构建最终应用程序的其他模块中的伴随C文件中调用回调。我不知道如何实现这个或类似的东西。我也对复杂的解决方案感兴趣。
答案 0 :(得分:3)
我没有看到跨包调用Go函数的方法,但是所有cgo包都链接到相同的二进制文件中并且可以相互调用。这意味着您可以将M.F导出到包M中的C函数,并从包Y和Z调用该C函数。
米/ m.go:
package m
// void F();
import "C"
import "fmt"
//export F
func F() {
fmt.Println("m.f")
}
米/莫氏硬度:
void m_f();
米/ M.C:
#include <stdio.h>
#include "_cgo_export.h"
#include "m.h"
void m_f() {
printf("m_f\n")
F();
}
Y / y.go:
package y
// The LDFLAGS lines below are needed to prevent linker errors
// since not all packages are present while building intermediate
// packages. The darwin build tag is used as a proxy for clang
// versus gcc because there doesn't seem to be a better way
// to detect this.
// #cgo darwin LDFLAGS: -Wl,-undefined -Wl,dynamic_lookup
// #cgo !darwin LDFLAGS: -Wl,-unresolved-symbols=ignore-all
// #include "y.h"
import "C"
import (
"fmt"
_ "m"
)
func Y() {
fmt.Println("y.Y")
C.y()
}
Y / y.h:
void y();
Y / y.c:
#include <stdio.h>
#include "../m/m.h"
void y() {
printf("y.C.y\n");
m_f();
}
答案 1 :(得分:0)
这是一个例子,它将接受任何go回调(非线程安全)。
b.go:
package b
// typedef void (*cbFunc) ();
// void do_run(cbFunc);
// void goCallback();
import "C"
//export goCallback
func goCallback() {
if goCallbackHolder != nil {
goCallbackHolder()
}
}
var goCallbackHolder func()
func Run(callback func()) {
goCallbackHolder = callback
C.do_run(C.cbFunc(C.goCallback))
}
b.c:
#include "_cgo_export.h"
void do_run(void (*callback)())
{
callback();
}
答案 2 :(得分:0)
我无法让它以简单的方式工作IMO。
鉴于导入X
和Y
的主程序包Z
,必须在程序包F
中声明(来自C源代码)M
,< / p>
我必须:
W1
中为F
创建一个小包装器Y
,然后将其导出以便从Y
的C源调用。W2
中为F
创建一个小包装器Z
,然后将其导出以便从Z
的C源调用。Y
CGO CPPFLAGS中定义-DCALLBACK=W1
Z
CGO CPPFLAGS中定义-DCALLBACK=W2
F
称为CALLBACK
(是的,内部它是所有不同的东西,我指的是在一端使用单个名称在另一端调用单个函数。)。这很复杂,但它正在工作,虽然配置这样的宏并产生很少的包装器 不理想。如果有人能详细说明一个更简单的程序,我会很高兴。一切 我尝试了重复的符号或不可见的声明。