我想在Golang中编写控制器逻辑并处理JSON和数据库,同时在C中使用我的数学处理模型. ,做一些fastcall并获得rax值.但是我听说过大 cgo 说我有常见的fastcall x64 c函数int64 f(int64 a,b,c,d){return a+b+c+d}如何从go中称呼它,以在GO testing.B基准中获得最高的潜在基准分数? ps没有指针传递,没有技巧,只是对如何以最强大的方式访问C接口 感兴趣 解决方案 我认为,开销C函数必须像设置寄存器RCX,RDX,RSI,RDI,DOIN fastCall并获得RAX值一样低.但是我听说过big cgo 您的意见是没有根据的. 从访问C的原因引起了注意的原因是以下原因. 让我们首先考虑C 虽然该语言不需要任何方式,但典型的编译器编制的典型C程序并在典型的操作系统上作为常规过程运行,但很大程度上依赖OS来执行其运行时环境的某些方面. 据说最明显和最重要的方面是堆栈:内核负责在加载
以下是关于 cgo 的编程技术问答
我正在尝试构建使用静态lib(.a file) 的Golang程序 我项目的目录结构如下 └─testserver ├─bin ├─pkg └─src ├─logging └─testserver ├─libtest.a └─test.go test.go中CGO的标志如下 // #cgo LDFLAGS: -L /home/test/testserver/src/testserver -ltest // #include "test.h" import "C" 当我使用ldflags -l的绝对路径时,它会罚款,但是当我更改相对路径的路径时,例如 // #cgo LDFLAGS: -L ./testserver -ltest 然后运行命令 go install testserver 它向我返回错误,并说"找不到-ltest" 我的问题
我已经搜索了几天,尝试了一些建议,但没有任何帮助.目前,我只想创建一个连接到Oracle数据库的小型GO片段.虽然一切都通过使用普通go build并调用生成的动态链接应用程序来工作,但当我尝试运行静态编译器时,我会卡住.我已经在没有问题的情况下静态地构建了其他项目(即使使用CGO),但是在这里GCC找不到Oracle库.也许有人有提示? 构建过程中的错误: host link: "gcc" "-m64" "-gdwarf-2" "-o" "/tmp/go-build319417544/command-line-arguments/_obj/exe/a.out" "-static" "/tmp/go-link-116023228/000000.o" "/tmp/go-link-116023228/000001.o" "/tmp/go-link-116023228/000002.o" "/tmp/go-link-116023228/go.o" "-g" "-O2" "-g" "
我正在使用CGO中的C代码接口,我需要用指针调用Interface{}对象中基础值的指针.该值将是任何原子原始类型(不包括complex64/complex128)或string. 我希望我能够做这样的事情,以ptr的地址为unsafe.Pointer: unsafe.Pointer(reflect.ValueOf(ptr).UnsafeAddr()) ,但由于值不可原值,这会导致恐慌. 与此类似的问题是在界面内获取值地址,但是这个问题是不同的,因为在这种情况下,众所周知,该值将始终是上面指定的类型之一(最多将是64位),我只需要将此值提供给C函数.请注意,有多个C函数,并且将被称为不同的无关参数的函数. . 我还尝试使用类型开关语句来解决此问题,但是即使完成类型断言,我也发现自己无法获得值的地址.我能够将这些值分配给临时副本,然后获取这些副本的地址,但是我宁愿避免使用这些副本. 解决方案 interface{}有自己的结构: type eface
package main /* int add(int a, int b) { return a + b; } */ import "C" import "fmt" func main() {} func Test1() { fmt.Println(C.add(1, 3)) } //export Test2 func Test2() { } 编译预制: dingrui@dingrui-PC:~/Projects/gotest/array$ go build -o libtest.so -buildmode=c-shared main.go # command-line-arguments /tmp/go-build043762604/b001/_x002.o: In function `add': ./main.go:5: multiple definition of `add' /tmp/go-build043762604/b001/_x001.o
我试图以相同的签名来调用C函数,他们进行了2个INT参数.此错误cannot call non-function f (type unsafe.Pointer)在编译期间出现. package main /* int add(int a, int b) { return a+b; } int sub(int a, int b) { return a-b; } */ import "C" import ( "fmt" "unsafe" ) func main() { a := C.int(1) b := C.int(2) fx := make([]unsafe.Pointer, 2) fx[0] = C.add fx[1] = C.sub for _, f := range fx { fmt.Printf("Result: %d\n", f(a, b)) } } 现在,我正在使用g
我正在写一个库,我想导出到c shared-library.它的工作正常,但是我发现导出的标头使用p0,p1,p2,...用于参数名称而不是GO中的原始参数名称,这有点烦人.有没有办法改变这种行为,或者我只是坚持这样做? 我正在使用go version go1.12.7 darwin/amd64 示例: package main /* #import */ import "C" import ( "fmt" ) func main() {} //export MyFunc func MyFunc(input *C.char) { fmt.Println(C.GoString(input)); } go build -o libout.so -buildmode=c-shared 输出: extern void MyFunc(char* p0); 为什么p0 input input? 根据这个cgo文档,
我想在Golang中调用C代码: // #cgo CFLAGS: -I/usr/include/c++/8.1.1/bits // #cgo CXXFLAGS: -std=gnu++11 // #include "c++0x_warning.h" import "C" 但获取错误: In file included from ./main.go:5: /usr/include/c++/8.1.1/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options. 因此,CGO不使用CXXFLAG.我尝试了-std=c++11,它也行不通
我有一个由CGO制成的共享库,它在Linux和Android上链接正常.但是,当使用Microsoft Visual Studio 2017上编译Windows 10时,我会得到这些错误: Microsoft (R) Program Maintenance Utility Version 14.16.27024.1 Copyright (C) Microsoft Corporation. All rights reserved. cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc -DUNICODE -
我正在尝试将多个GO Carchive软件包包含在单个C二进制中,但是由于每个C架构中包含了完整的运行时,我会遇到多个定义错误. 我尝试将多个软件包放在同一C架构中,但GO Build不允许这样做. 我还尝试从除一个档案外的所有档案中删除go.o,但是我自己的GO代码似乎也在该对象文件中,因此不起作用,这甚至是我获得多个定义的原因从后续档案中忽略go.o的链接器. 使用c-shared而不是c-archive,我不想这样做,因为我不得不将共享库放在我的目标机器上,这比仅放置了更复杂最终程序在那里.如果可能的话,我希望一切都可以静态链接. 有没有办法使此工作?我只能接受Linux的解决方案(在这种情况下可能有些GNU ld骗局). . 将所有内容都放在单个GO包中并不是一个选择,因为它是一个相当大的代码库,并且需要不同的程序需要不同的零件.在这种情况下,它必须是自动生成的软件包. 重现问题的完整步骤: cd $GOPATH/src mkdir a b
我想使用从Golang构建的WebAssembly库来编写JS脚本. 但是我需要使用C库并通过CGO使用. 简而言之,我的代码看起来像这样(仅加载c库的示例): package main /* #include */ import "C" func main() { println("Hello") } 但是,当我想在带有命令的教程中构建它时,我有错误. 命令: GOARCH=wasm GOOS=js go build -o lib.wasm test.go 输出: can't load package: package main: build constraints exclude all Go files in [Project path] 所以我的问题更多是否可以构建这样的东西. 谢谢. 解决方案 不会飞:GOARCH=wasm GOOS=js基本上使GO编译器从 go source中产生 w
编辑:将标题更改为更好地反映问题,这要多于@NOT_A_GOLFER 我一直在尝试GO,无法弄清楚这个问题. 以下当主包中包含以下功能正常: // Define a callback-function type, and define an invoker for it type Callback func(i C.int, d C.double) func Invoke(cb Callback, i C.int, d C.double) { cb(i, d) } //... then define my callback and pass it into the invoker func foo(i C.int, d C.double) { fmt.Printf("i %d d %f\n", i, d) } func main() { Invoke(foo, 2, 2.2) } 但是,当我在软件包中定义type Ca
我有一个类似的结构: typedef struct st_MASK_SETTINGS { uint32_t foo : 1; uint32_t bar : 7; } MASK_SETTINGS 现在通过CGO我想访问foo - 但是找不到任何文档如何做. naive v := ms.foo投诉has no field or method. 解决方案 好吧,您不会喜欢这个答案,但是 没有便携式方法可以做到这一点,因为Bitfield包装在C和C ++中均为"实现定义",并且 Go中的Bitfield支持似乎相当糟糕(也许是由于#1). 首先,Bitfields的布局在每个现有的C和C ++标准中都定义.这意味着没有任何标准指定应该如何包装比特定义中的位(即,应该去哪里) - 完全取决于编译器.在实践中,您可能会发现它们如何布置为某种方式 给定一些编译器样本,但是您将深入到不确定的行为领域. 我们正在 bug#83784 (通过"我们"
我正在尝试在同一目录中使用单独的C源文件创建一个CGO程序.如官方CGO文档中所述,CGO将在同一目录中编译所有C文件,但在这种情况下,它不会编译C文件.后来给出链接器错误. mytest.go package main /* #include #include "myTest.h" */ import "C" import "unsafe" func Print(s string) { cs := C.CString(s) C.print_str(cs) C.free(unsafe.Pointer(cs)) } func main() { str1 := "hi how are you\n" Print(str1) } mytest.h void print_str(char *s); mytest.c #include "stdio.h" void print_str(char
我正在尝试将C ++代码包括在我的GO代码中,但未识别. 我首先认为它将其视为C代码,并尝试(并且失败)这样进行编译,但是删除Include Line实际上会给我C ++错误的错误排除. error: ‘cout’ is not a member of ‘std’ 该代码使用G ++正确编译. 我尝试添加-lstdc ++ ldlflag,并将路径添加到cxxflag中的lib,但不会改变任何事情. 我做了其他一些测试(所有这些都失败),但这是最小的测试. 这是C ++文件 test.cpp #include "test.hpp" int test() { std::cout int test() ; 这是我的GO文件 //#cgo CXXFLAGS: -I/us
我正在尝试使用. 我用记录的-buildmode c-shared构建了包裹. -buildmode=c-shared Build the listed main package, plus all packages it imports, into a C shared library. The only callable symbols will be those functions exported using a cgo //export comment. Requires exactly one main package to be listed 并使用//export Func将函数公开为C符号. main包装中的所有//export函数都正确导出.但是,当我将这些功能移至子包装(带有//export)时,这些功能不会导出.我也在main软件包中导入了子包. 这是我的代码. main.go package
我正在包装一个C库,该C库具有一个带有void*数据字段的结构,可用于任意保存数据.将其包裹在惯用的方法中的最好方法(如果有可能的话)是什么? 结构很简单: typedef struct _Foo { void * data; } Foo; 我希望做类似的事情: type Foo C.Foo func (f *Foo) SetData(data interface{}) { f.data = unsafe.Pointer(&data) } func (f *Foo) Data() interface{} { return (interface{})(unsafe.Pointer(f.data)) } 这不起作用,显然是错误的方法. 我使用[]字节源成功设置了一个带有长度字段的void*数据,但是这个无长度的接口使我感到不安. 解决方案 在我的腰带上再去几个月后,我想到了以下(已更新,感谢Zupa)解决方案. .
我想从go [] []字节转换为c ** char.换句话说,我有一个字节矩阵,我想在c. 中转换为char double指针 请假设我必须有一个[] []字节作为输入,而char作为输出. 我知道可以通过执行以下操作来从[]字节转换为 *char ((*C.char)(unsafe.Pointer(&data[0]))) ,但似乎不可能将这种情况扩展到第二维.我尝试了一些非常复杂的东西,其中我将[] []字节打包到一个新的[]字节中.然后,我将该[]字节发送到C函数,该C函数使用指针算术创建一个** char以指向正确位置的新[]字节. 这种转换给我带来了奇怪的行为,我的数据对于一些迭代是正确的,但在函数调用之间看似损坏. 如果有人有任何想法,我真的很感激. 从我看到的响应来看,也必须说明我正在使用原始数据而不是字符串.因此,GO字节类型.因此,如果添加C字符串终止器,原始数据将损坏.我只是在使用c ** char,因为char是一个大小的字节.就是说