标签: cgo

将 Go 函数作为回调传递给 C

假设我有一个 C 库,代码如下:

typedef int (callback_t)(int);
void register_callback(callback_t cb);
Run Code Online (Sandbox Code Playgroud)

我想为此函数编写 go 绑定并传递任意 go 回调。

我在这里找到了一个很好的答案。然而,这是一个利用回调接受 a 的事实的技巧void *,Go 通过它将函数指针传递给 C 并接收它。但是,这不能应用于我的示例,因为没有 user void *

我能做的最好的事情是:

/*
extern int gobridge(int data);

static int cbridge(void)
{
    register_callback(gobridge);
}
*/
import "C"

type Callback func (int) int

var g_cb Callback

//export gobridge
func gobridge(data C.int) C.int {
    return C.int(g_cb(int(data)))
}

func RegisterCallback(cb Callback) {
    g_cb = cb //save callback in a global
    C.cbridge()
}

func Count(left, right int) { …
Run Code Online (Sandbox Code Playgroud)

c binding go cgo

5
推荐指数
1
解决办法
2167
查看次数

有什么方法可以捕获 cgo 代码中触发的致命错误吗?

我们的应用程序使用odbc驱动程序来访问 Impala 数据库。我们发现,在某些难以复制的情况下,驱动程序将在其 cgo 代码中触发段错误,一旦它通过驱动程序传播回我们的代码,就会表现为致命错误。由于我们希望在这些情况下进行一些清理和警报,因此我实现了一个延迟的恐慌捕捉器,希望这可以捕捉到它们。

但是,它不起作用。致命错误继续直接经过包含调用的延迟函数recover()(因此显然这不是恐慌,尽管打印输出看起来相似),尽管它确实捕获了其他恐慌。github 问题表明无法捕获 cgo 信号,并且如果发生这种情况,应用程序应该立即崩溃。对于我们的生产应用程序来说,这是一个不可接受的崩溃案例,所以我想知道过去 6 年来这种情况是否发生了变化,或者是否有人知道在出现 cgo 信号时运行一些清理代码的另一种方法。根本无法捕获和处理这些致命错误,这似乎是极其糟糕的设计。

go cgo

5
推荐指数
0
解决办法
1458
查看次数

如何在 CGO 中包装库(具有 c++11 功能)

  1. 我的操作系统是 Mac,编译器是 clang
  2. 我想在 Go 中包装一个 C++ 库(openfst,它使用 C++11 功能)
  3. 我遇到了由 c++11 问题引起的错误。似乎 fstlib.h 包含一些使用 c++11 语法的头文件。
In file included from gofst.cpp:2:
In file included from /usr/local/include/fst/fstlib.h:28:
In file included from /usr/local/include/fst/expanded-fst.h:13:
In file included from /usr/local/include/fst/log.h:26:
/usr/local/include/fst/flags.h:143:50: error: a space is required between consecutive right angle brackets (use '> >')
/usr/local/include/fst/flags.h:174:37: error: a space is required between consecutive right …
Run Code Online (Sandbox Code Playgroud)

clang go c++11 cgo openfst

5
推荐指数
0
解决办法
3502
查看次数

Go 中的 size_t 不使用 cgo

这是一个我想移植到Go 结构中的C 结构

struct InputBuffer_t {
   char* buffer;
   size_t buffer_length;
   ssize_t input_length;
};
Run Code Online (Sandbox Code Playgroud)

但是有一种方法可以在Go中声明buffer_length变量,而无需使用C.size_t cgo 指针

这是对可移植性的担忧。如果我这样写Go 结构体,它会是可移植的吗?

type InputBuffer struct {
   Buffer        string
   BufferLength uint32
   InputLength  uint32
};
Run Code Online (Sandbox Code Playgroud)

struct go cgo

5
推荐指数
0
解决办法
2848
查看次数

如何在多个 .go 文件中包含一个头文件?

我有一个标头foo.h和两个源文件main.go以及bar.go.

foo.h包含两个函数:foo(),bar()

main.go我的呼唤中C.foo(),在bar.go我的呼唤中C.bar()

两者都导入伪包“C”和#include "foo.h"

虽然我添加了包含防护foo.h,但我收到以下错误:

在函数中foo::/path/too/foo.h的多个定义foo

同样对于功能bar()

go cgo

5
推荐指数
0
解决办法
994
查看次数

cgo如何抑制警告

我有一个使用 C 库的 cgo 应用程序。在构建过程中,编译器会显示一些警告:

In file included from ./libsolv-sys/src/qsort_r.c:40:0,
                 from ./libsolv-sys/src/util.c:181,
                 from ./libsolv.go:16:
/usr/include/sys/cdefs.h:1:2: warning: #warning usage of non-standard #include <sys/cdefs.h> is deprecated [-Wcpp]
 #warning usage of non-standard #include <sys/cdefs.h> is deprecated
  ^~~~~~~
Run Code Online (Sandbox Code Playgroud)

该库不是由我自己维护的,我无法直接修复此警告。不过我厌倦了这个警告。

问题:如何抑制 CGO 中的警告?

使用过的 CGO 旗帜: CFLAGS: -I./libsolv-sys/src -D LIBSOLV_INTERNAL LDFLAGS: ${SRCDIR}/libsolv-sys.a

go cgo

5
推荐指数
1
解决办法
2513
查看次数

CGO 中的 golang 结构体与 C 结构体

我将使用cgo将一个c库包装为go库以供项目使用。我看了文档,好像使用cgo有很多规则。我不知道这是否合法。

LibCtx 和 Client 都是 C 中的结构体。这是将 C 结构体放入 golang 结构体中的合法方法吗?

//DBClientLib.go

type DBClient struct {
    Libctx C.LibCtx
    LibClient C.Client
}

func (client DBClient) GetEntry(key string) interface{} {

    //...
}
Run Code Online (Sandbox Code Playgroud)

go cgo

5
推荐指数
1
解决办法
1万
查看次数

Golang:CGO移植包的多重定义

我有2个项目,第一个,名称为A,有一个子模块a导入sqlite3( github.com/mattn/go-sqlite3)。另一个B项目导入的A子模块a,并且在另一个子模块中b,它也导入相同的sqlite3。

并将导入放在 dir 下A(由 管理)。我的 Golang 版本是.Bvendorgovendorgo version go1.12 linux/amd64

在构建Bgo build main.go)时,抛出以下错误(太多,部分错误):

 /usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
 /tmp/go-link-281256755/000029.o: In function `callbackTrampoline':
 /tmp/go-build/_cgo_export.c:25: multiple definition of `callbackTrampoline'
 /tmp/go-link-281256755/000005.o:/tmp/go-build/_cgo_export.c:25: first defined here
 /tmp/go-link-281256755/000029.o: In function `stepTrampoline':
 ...
 /home/xxx/go/src/gitlab.xxxxxxxxx.com/xxxxxxxxx-tools/A/vendor/github.com/mattn/go-sqlite3/sqlite3.go:129: multiple definition of `_sqlite3_result_text'
 /tmp/go-link-281256755/000009.o:/home/xxx/go/src/gitlab.xxxxxxxxx.com/xxxxxxxxx-tools/A/vendor/github.com/mattn/go-sqlite3/sqlite3.go:129: first defined here
 /tmp/go-link-281256755/000033.o: In function `_sqlite3_result_blob':
 ...
Run Code Online (Sandbox Code Playgroud)

但建筑A效果很好。为了测试错误,我开始关注演示,也使用vendor …

linker go cgo

5
推荐指数
1
解决办法
2827
查看次数

使用 swig 从 C++ 调用 go

我正在使用 swig 将 c++ 与 go 链接起来,但我想在我的 c++ 代码中使用 go 函数。我以前使用过 cgo,并且知道这样的东西会起作用:

//bind.h
extern void GoFunc(*C.char);
void CFunc();
//////////////////


//bind.cc
void CFunc() {
  //do stuff
}
//////////////////


//main.go
package main

//#include "bind.h"
import "C"

//export GoFunc
func GoFunc(*C.char) {
  //do go stuff
}

func main() {
  C.CFunc()
}
//////////////////
Run Code Online (Sandbox Code Playgroud)

但当我尝试在痛饮中复制这一点时,

//bind/bind.i
%module bind
%{
  extern void Foo();
  #include "bar.hpp"
%}

%include <typemaps.i>
%include "bar.hpp"
///////////////////////////


//bind/bar.hpp
class Bar {
  Bar() {}
  void Call() {
    Foo();
  }
};
///////////////////////////


//main.go
package …
Run Code Online (Sandbox Code Playgroud)

c++ swig go cgo

5
推荐指数
0
解决办法
582
查看次数

在 Go + SWIG + C++ 代码中清理内存管理

我通过 SWIG 使用 Go 的 C++ 库。SWIG 不负责内存管理,因此 Go 端看起来像这样:

f := NewFoo()
defer DeleteFoo(f)
Run Code Online (Sandbox Code Playgroud)

DeleteFoo(f)当我创建 时,调用它很容易f,但对于 C++ 函数的返回值很容易忽略它。

我想自动检查我的代码是否做正确的事情。

我看到 Address Sanitizer 是为 GCC 和 Clang 实现的,这听起来是正确的。但我找不到一个明确的方法来说明如何为我的go test命令启用它。

c++ swig go cgo address-sanitizer

5
推荐指数
1
解决办法
418
查看次数

标签 统计

cgo ×10

go ×10

c++ ×2

swig ×2

address-sanitizer ×1

binding ×1

c ×1

c++11 ×1

clang ×1

linker ×1

openfst ×1

struct ×1