我将此作为问题/答案发布,因为我花了一段时间才解决问题,我不介意对我的解决方案提出一些反馈意见.在Go/CGo中,如何使用作为指针传递的C数组?
例如,使用此C结构:
struct _GNetSnmpVarBind {
guint32 *oid; /* name of the variable */
gsize oid_len; /* length of the name */
... and other fields
};
Run Code Online (Sandbox Code Playgroud)
我想将oid字段转换为Go字符串,我将如何使用guint32*指针?
假设我想使用一些很棒的go包.我可以通过以下方式加入:
import "github.com/really-awesome/project/foobar"
Run Code Online (Sandbox Code Playgroud)
在该项目的foobar.go文件中,它定义了一些cgo指令,如:
#cgo windows CFLAGS: -I C:/some-path/Include
#cgo windows LDFLAGS: -L C:/some-path/Lib -lfoobar
Run Code Online (Sandbox Code Playgroud)
但如果我在foobar其他地方安装了C依赖项,我真的需要这些行说:
#cgo windows CFLAGS: -I C:/different-path/Include
#cgo windows LDFLAGS: -L C:/different-path/Lib -lfoobar
Run Code Online (Sandbox Code Playgroud)
有没有办法覆盖或特朗普在哪里cgo寻找这些依赖?现在我的修复是在运行后手动编辑这两行,go get ./...这将获取github.comreally-awesome/project/foobar代码.
注意:我正在使用MinGw编译器,但我怀疑这很重要.
我试过添加标志来构建无济于事:
go build -x -gcflags="-I C:/different/include -L C:/different-path/lib -lfoobar"
go build -x -ccflags="-I C:/different/include" -ldflags="-L C:/different-path/lib -lfoobar"
Run Code Online (Sandbox Code Playgroud)
通过-x参数,我看到了标志的打印输出,它们不包括我在命令行上设置的标志.也许#cgo CFLAGS/LDFLAGS外部go包顶部的陈述压制我告诉它使用的...
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) 我正在尝试在我的Windows 10上使用gopacket.
我正在使用它来嗅探并直接向NIC注入数据包.
我可以使用GOARCH = 386轻松编译和运行我的代码,但不能在GOARCH = amd64中.
值得注意的是:我不是在尝试交叉编译.
我正在使用go1.6.windows-386来编译32位版本,当我尝试用GOARCH = amd64编译时,我使用go1.6.windows-amd64.
我使用TDM-GCC作为linux编译工具.
该错误不是指示性的.它只是说
c:/WpdPack/Lib/x64/wpcap.lib: error adding symbols: File in wrong format
collect2.exe: error ld returned 1 exit status
有没有人设法建立这个,如果它甚至可能?
我想通过CGO将Go字符串复制到char*中.
我可以这样做吗?
func copy_string(cstr *C.char) {
str := "foo"
C.GoString(cstr) = str
}
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试在Go项目中添加一些C代码.没有什么花哨
/*
#include <stdio.h>
void test() {
printf("hooola")
}
*/
import (
"C"
)
func MessageBox() {
C.test()
}
Run Code Online (Sandbox Code Playgroud)
然而,这将返回
cc1.exe:抱歉,未实现:64位模式未编译
我检查了我g++和gcc编译器,一切似乎都很好,g++ -v返回此
C:\Users\ragga>g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw-w64/x86_64-6.2.0-posix-seh-rt_v5-rev1/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/6.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-6.2.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw620/x86_64-620-posix-seh-rt_v5-rev1/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-isl-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw620/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw620/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw620/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw620/prerequisites/x86_64-w64-mingw32-static …Run Code Online (Sandbox Code Playgroud) 最近我一直libsodium在使用cgo 设置我的一个项目,以便使用crypto_pwhash_str和crypto_pwhash_str_verify功能.
这一切都非常顺利,我现在有一小部分函数,它们[]byte以纯文本密码的形式接收并散列它,或者将它与另一个[]byte进行比较以验证它.
我使用的一个原因[]byte,而不是string因为,从我迄今约去学,我可以过明文密码至少循环和零所有字节,甚至将指针传递到libsodium的sodium_memzero功能,为了不让它在内存中停留超过它需要的时间.
这对于我能够直接以字节读取输入的应用程序来说很好,但我现在正尝试在一个小型Web应用程序中使用它,我需要使用该POST方法从表单中读取密码.
从我在Go源代码和文档中看到的内容,r.ParseForm在请求处理程序中使用将所有表单值解析map为strings.
问题是因为stringGo中的s是不可变的,我不认为我可以做任何关于POST将表单中编写的密码的内存归零的事情; 至少,只使用Go.
因此,似乎我唯一的(简单)选项是将unsafe.Pointer一个函数传递给C中的函数以及字节数,让C为我归零内存(例如,将其传递给上述sodium_memzero函数).
我已经尝试了这一点,并且毫不奇怪它当然有效,但是我string在Go中留下了一个不安全的东西,如果在一个函数中使用它fmt.Println会使程序崩溃.
我的问题如下:
POST编辑并解析为字符串,我不应该把它搞乱,只是等待GC启动?(不理想)string使用cgo ok 的内存清零,前提是代码中明显记录了字符串变量不应该再次使用?string使用cgo 的内存清零会不会像崩溃一样?http.Request添加一个直接解析表单值的函数,[]byte因此我可以在它们到达时完全控制值?编辑:为了澄清,网络应用程序和表单POST只是一个简单的例子,我可能只是使用Go的标准库以一种形式传递敏感数据string.我更感兴趣的是我的所有问题是否可能/值得在某些情况下尽可能快地清理内存中的数据更多是一个安全问题.
我正在努力建立一个标准的"Hello,World!" Android的命令行可执行文件.可执行文件将通过运行adb shell.
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, world!")
}
Run Code Online (Sandbox Code Playgroud)
$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build .
Run Code Online (Sandbox Code Playgroud)
# github.com/asukakenji/cross
warning: unable to find runtime/cgo.a
/usr/local/go/pkg/tool/darwin_amd64/link: running clang failed: exit status 1
ld: warning: ignoring file
/var/folders/dd/6k6vkzbd6d5803xj9zkjdhmh0000gn/T/go-link-150305609/go.o,
file was built for unsupported file format
( 0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 )
which is not the architecture being linked …Run Code Online (Sandbox Code Playgroud) 这是我的代码:
package main
import (
kusb "github.com/karalabe/usb"
tusb "github.com/trezor/trezord-go/usb"
)
func main() {
kusb.Enumerate(0, 0)
tusb.InitHIDAPI(nil)
}
Run Code Online (Sandbox Code Playgroud)
当我编译时(我用来go mod管理包),它返回以下错误:
duplicate symbol _libusb_dev_mem_alloc in:
/var/folders/fm/1rln65d94mn45s0h5l78tdyh0000gp/T/go-link-624554542/000002.o
/var/folders/fm/1rln65d94mn45s0h5l78tdyh0000gp/T/go-link-624554542/000020.o
ld: 136 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
为什么?
我进行了一些调查:
hidapiClibusb包来与 USB 设备交互。trezord-go/usb,它们包含.C文件,而不是头文件。这对我来说非常违反直觉,因为从包用户的角度来看,我不需要担心 C 包在包内部如何使用,只需要担心公开的类型、函数及其行为。
谁能真正解释一下这里发生了什么以及我如何导入它们?尽管它们使用相同的 C 包,但它们执行不同的功能。
请看下面的截图:
它说:
无法导入 C(导入路径 C 没有包数据)
我附上了一个重现失败的示例项目,在这里:https : //github.com/microsoft/vscode/files/3783446/example-project.zip
我将 Go 1.13 与 Go 和 C/C++ 的每个扩展的最新版本一起使用。没有编译器错误,这似乎是一个“vscode 问题”。
有没有办法解决这个 vscode 问题?