标签: cgo

将结构和结构数组从Go传递给C函数

坚持这个问题.能够只获得通过结构的第一个成员......我做错了什么?将结构从Go传递给C的正确方法是什么?

这是我如何工作的例子:

package main

/*
#include <stdio.h>

typedef struct {
    int a;
    int b;
} Foo;

void pass_array(Foo **in) {
    int i;

    for(i = 0; i < 2; i++) {
        fprintf(stderr, "[%d, %d]", in[i]->a, in[i]->b);
    }
    fprintf(stderr, "\n");
}

void pass_struct(Foo *in) {
    fprintf(stderr, "[%d, %d]\n", in->a, in->b);
}

*/
import "C"

import (
    "unsafe"
)

type Foo struct {
    A int
    B int
}

func main() {

    foo := Foo{25, 26}
    foos := []Foo{{25, 26}, {50, 51}}

    // wrong …
Run Code Online (Sandbox Code Playgroud)

go cgo

8
推荐指数
3
解决办法
7622
查看次数

使用cgo将函数指针传递给C代码

从Go v1.6开始,cgo改变了将指针传递给C代码golang/go#12416的规则.从wiki的C代码调用动态Go回调的示例不再起作用.

package main

import (
    "fmt"
    "unsafe"
)

/*
   extern void go_callback_int(void* foo, int p1);

   // normally you will have to define function or variables
   // in another separate C file to avoid the multiple definition
   // errors, however, using "static inline" is a nice workaround
   // for simple functions like this one.
   static inline void CallMyFunction(void* pfoo) {
       go_callback_int(pfoo, 5);
       }
*/
import "C"

//export go_callback_int
func go_callback_int(pfoo unsafe.Pointer, p1 C.int) {
    foo := *(*func(C.int))(pfoo)
    foo(p1) …
Run Code Online (Sandbox Code Playgroud)

go cgo

8
推荐指数
2
解决办法
6643
查看次数

".text"部分中的cgo错误无法识别的重定位(0x2a)

使用Cgo构建Go程序时出现错误

/usr/lib/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-373355991/000002.o: unrecognized relocation (0x2a) in section `.text'
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

尝试谷歌那个问题,并发现Debian和Ubuntu上的一些错误(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=808205)与libc6(2.21)版本中的C编译器和链接器比我使用的版本更新(2.19).

还有提到编译C程序时遇到问题,我在C中成功编译了示例.

我尝试在具有相同系统和库版本的其他机器上构建我的Go程序,并且构建成功.

debian go cgo

8
推荐指数
1
解决办法
4021
查看次数

如何从谷歌导入和使用CGO Brotli实现?

我正在尝试导入并使用谷歌的cbrotli实现,如下所示:

import (
    "fmt"
    "io/ioutil"

    cbrotli "github.com/google/brotli/go/cbrotli"
)
Run Code Online (Sandbox Code Playgroud)

但是在尝试运行程序时出现以下错误:

learn-go [master??] % CGO_CFLAGS="-I /dev/projects/go/learn-go/src/brotli/c/include/brotli" go run cmd/compress/main.go
# github.com/google/brotli/go/cbrotli
src/github.com/google/brotli/go/cbrotli/reader.go:13:10: fatal error: 'brotli/decode.h' file not found
#include <brotli/decode.h>
Run Code Online (Sandbox Code Playgroud)

我不知道如何传递一些C标志以确保我可以使用brotli实现

go cgo brotli

8
推荐指数
1
解决办法
443
查看次数

交叉编译时,Golang 无法在 x86_64 机器上链接 aarch64/arm64 二进制文件

我正在尝试为 x86_64 桌面上的 aarch64 机器交叉编译https://github.com/joohoi/acme-dns 。

\n
$ CC=aarch64-linux-gnu-gcc GOOS=linux GOARCH=arm64 CGO_ENABLED=1 go build -v -ldflags="-extld=$CC"\n# github.com/mattn/go-sqlite3\nsqlite3-binding.c: In function \xe2\x80\x98sqlite3SelectNew\xe2\x80\x99:\nsqlite3-binding.c:125322:10: warning: function may return address of local variable [-Wreturn-local-addr]\n125322 |   return pNew;\n       |          ^~~~\nsqlite3-binding.c:125282:10: note: declared here\n125282 |   Select standin;\n       |          ^~~~~~~\n# github.com/joohoi/acme-dns\n/usr/lib/go-1.15/pkg/tool/linux_amd64/link: running gcc failed: exit status 1\n/usr/bin/ld: /tmp/go-link-266874795/go.o: Relocations in generic ELF (EM: 183)\n/usr/bin/ld: /tmp/go-link-266874795/go.o: Relocations in generic ELF (EM: 183)\n/usr/bin/ld: /tmp/go-link-266874795/go.o: Relocations in generic ELF (EM: 183)\n/usr/bin/ld: /tmp/go-link-266874795/go.o: Relocations in generic ELF (EM: 183)\n/usr/bin/ld: /tmp/go-link-266874795/go.o: Relocations …
Run Code Online (Sandbox Code Playgroud)

cross-compiling go cgo

8
推荐指数
1
解决办法
2576
查看次数

如何在golang中使用LDFLAGS的相对路径

我是Golang的新手,我正在尝试构建一个使用静态库(.a文件)的golang程序

我的项目的目录结构如下

??testserver
    ??bin
    ??pkg
    ??src
        ??logging
        ??testserver
            ??libtest.a
            ??test.go
Run Code Online (Sandbox Code Playgroud)

test.go中的cgo标志如下

// #cgo LDFLAGS: -L /home/test/testserver/src/testserver -ltest
// #include "test.h"
import "C"
Run Code Online (Sandbox Code Playgroud)

当我使用LDFLAGS -L的绝对路径时,它会产生罚款,但是当我将路径更改为相对路径时,例如

// #cgo LDFLAGS: -L ./testserver -ltest
Run Code Online (Sandbox Code Playgroud)

然后运行该命令

go install testserver
Run Code Online (Sandbox Code Playgroud)

它向我返回一个错误,并说"找不到-ltest"

我的问题是如何在LDFLAGS中使用相对路径?,以便我可以在任何路径上构建项目.谢谢!

path relative-path go ldflags cgo

7
推荐指数
1
解决办法
7731
查看次数

使用OS X上的cgo到linux和windows进行1.5交叉编译

git2go在将1.4.2升级到1.5之后,我在将OS X上的库编译为linux amd64时遇到了问题.

我认为这是关于交叉编译任何使用C代码和go 1.5的应用程序.

使用CGO_ENABLED=1,我得到:

$ CGO_ENABLED=1 GOOS=linux GOARCH=amd64 ./script/with-static.sh go install ./...
# runtime/cgo
ld: unknown option: --build-id=none
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

使用-compiler=gccgo,我得到:

$ GOOS=linux GOARCH=amd64 ./script/with-static.sh go install -compiler gccgo ./...
go build github.com/libgit2/git2go: : fork/exec : no such file or directory
Run Code Online (Sandbox Code Playgroud)

如果没有提供任何这些,我得到:

$ GOOS=linux GOARCH=amd64 ./script/with-static.sh go install ./...
can't load package: package github.com/libgit2/git2go: C source files not allowed when not …
Run Code Online (Sandbox Code Playgroud)

cross-compiling go libgit2 cgo gccgo

7
推荐指数
1
解决办法
4312
查看次数

在 C# 中从 Go 调用函数

我正在尝试从 Golang 制作一个 .dll 文件以在 C# 脚本中使用。但是,我无法使一个简单的示例起作用。

这是我的 Go 代码:

package main

import (
    "C"
    "fmt"
)

func main() {}

//export Test 
func Test(str *C.char) {
    fmt.Println("Hello from within Go")
    fmt.Println(fmt.Sprintf("A message from Go: %s", C.GoString(str)))
}
Run Code Online (Sandbox Code Playgroud)

这是我的 C# 代码:

using System;
using System.Runtime.InteropServices;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello");
            GoFunctions.Test("world");
            Console.WriteLine("Goodbye.");
        }
    }


    static class GoFunctions
    {
    [DllImport(@<path to test.dll>, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
    public static extern void Test(string str);
    } …
Run Code Online (Sandbox Code Playgroud)

c# dll go cgo

7
推荐指数
1
解决办法
2225
查看次数

如何分发具有 C 依赖项的 Go 模块

我有一个 Go 包(称之为它)foo,我围绕一些现有的 C 代码构建了它,并且我正在尝试确定如何最好地分发它。

一些背景知识...这是我的目录结构的简化版本:

foo/
  |_ include/
      |_ <several other header files>
  |_ libs/
      |_ <several .so files>
  |_ foo.c
  |_ foo.h
  |_ foo.go
Run Code Online (Sandbox Code Playgroud)

一个被剥光的头foo.go

foo/
  |_ include/
      |_ <several other header files>
  |_ libs/
      |_ <several .so files>
  |_ foo.c
  |_ foo.h
  |_ foo.go
Run Code Online (Sandbox Code Playgroud)

_foo.so作为构建过程的一部分生成的动态库在哪里。我能够很好地运行和测试我的代码,但我希望能够分发它并在一个单独的项目(使用go mod. 这就是事情变得有点棘手的地方,而且我对 Go 的理解也变得脆弱。从概念上讲,我只是希望能够将foo/目录(.so文件和所有内容)分发到另一个应用程序可以找到并导入它的位置,但是我遇到了一些障碍:

  • 我无法将其作为二进制包,因为我们使用的是 Go 1.13,并且据我所知,该功能在 1.12 后已被删除。
  • 该文件的构建过程.so非常重要,我不希望其他开发人员花费 30 分钟以上的时间来构建该对象。

我找到了很多 CGO 演示和博客,但没有很多关于如何分发 CGO 包的解释。有任何想法吗?

值得注意的是,这是针对我的公司的,环境是标准的,所以我不必控制不同的操作系统等。

编辑

我忘记提及我尝试过的一件事是将库烘焙到 …

go cgo go-modules

7
推荐指数
1
解决办法
3061
查看次数

从 golang 到 c (cgo) 的 SetEvent 状态

我编写了 DLL 来处理我在 golang 中的 VSCAN 通信。我现在面临着一个非常棘手的问题。有没有办法将状态从 cgo 发送到 c/cpp 程序?

我正在使用一个大型 CPP 项目,在它内部调用外部 golang DLL(用 GCC 编译)。程序通过事件句柄:

    // this is a function from DLL (written in go). I want to pass the event handler there.
    VSCAN_STATUS VSCAN_SetRcvEvent(VSCAN_HANDLE Handle, HANDLE Event);

    // Calling it from c:
    sg_hEventRecv = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    VSCAN_SetRcvEvent(1, sg_hEventRecv)
Run Code Online (Sandbox Code Playgroud)

我将传递的 HANDLER 存储在 go dll 中:

package test

import "C"

var event C.HANDLE
func signalState(){
C.SetEvent(event) 
}

//export VSCAN_SetRcvEvent
func VSCAN_SetRcvEvent(Handle VSCAN_HANDLE, Event C.HANDLE) int { …
Run Code Online (Sandbox Code Playgroud)

dll events go cgo

7
推荐指数
0
解决办法
104
查看次数

标签 统计

cgo ×10

go ×10

cross-compiling ×2

dll ×2

brotli ×1

c# ×1

debian ×1

events ×1

gccgo ×1

go-modules ×1

ldflags ×1

libgit2 ×1

path ×1

relative-path ×1