我在 Go 代码中创建 C 结构体,如下所示:
var data C.MyStruct_t
Run Code Online (Sandbox Code Playgroud)
我是否必须在某个时候手动释放它们,就像使用 CString 时所做的那样?使用 CString 我经常做这样的事情:
ctitle := C.String(title)
defer C.free(unsafe.Pointer(&ctitle))
C.my_func(&ctitle)
Run Code Online (Sandbox Code Playgroud) 我目前正在编写一些基本的 cgo 代码。根据关于 Go to C 参考的cgo 文档:
要直接访问 struct、union 或 enum 类型,请在其前面加上 struct_、union_ 或 enum_ 前缀,如 C.struct_stat 中所示。
我对这句话的理解是,如果我有一个Foo用 C命名的结构体,我必须使用C.struct_FooGo 中的类型。
我写了一些 Go 代码,如:
package main
// #cgo LDFLAGS: -lnavilink -lserialport
// #cgo CFLAGS: -I/usr/local/include
// #include<navilink/navilink.h>
import "C"
import "errors"
func (d *Device) navilinkErrorToGoError() error {
errorC := C.navilink_get_error_description(d.navilinkC)
return errors.New(C.GoString(errorC))
return nil
}
// Device représente une interface
// vers le port série connecté au GPS
type Device struct …Run Code Online (Sandbox Code Playgroud) 我有一个cgo程序:
package main
//#define sum(a,b) (a)+(b)
import "C"
func main() {
print(C.sum(1,2))
}
Run Code Online (Sandbox Code Playgroud)
它应该非常简单并打印 3。但是编译失败:
could not determine kind of name for C.sum
Run Code Online (Sandbox Code Playgroud)
由于我发现 cgo 的文档有限,并且经过一些测试,cgo 可与宏常量一起使用,但如何让它与宏函数/参数一起使用?
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() {
}
Run Code Online (Sandbox Code Playgroud)
编译程序:
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:/tmp/go-build/main.go:5: first defined here
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
如果我删除“//export Test2”行,它就会成功编译。
我正在尝试从 C++ 调用 Go。我的代码在地图上运行,我似乎无法使地图与 cgo 一起使用。
main.go:
package main
import (
"C"
"fmt"
)
func main() {}
//export PrintMap
func PrintMap(m map[string]string) {
fmt.Println(m)
}
Run Code Online (Sandbox Code Playgroud)
其中“编译”为main.h:
typedef void *GoMap;
extern void PrintMap(GoMap p0);
Run Code Online (Sandbox Code Playgroud)
如何在我的 c++ 代码中成功创建 GoMap 并将其传递给 go 代码?
目前我正在使用Cgo从Go调用C函数.我正试图在Go中重新创建"Read a Photo"示例.
然而,关于C函数的一个期望一个int* len论证(奖金问题;是否与int *len?相同).当我读到这个时,这是一个指向整数的指针.有问题的函数是ccv_writelibccv库.它的完整签名是:
int ccv_write(ccv_dense_matrix_t* mat, char* out, int* len, int type, void* conf)
相关的代码段如下:
type Image struct {
image *C.ccv_dense_matrix_t
}
func main() {
image := new(Image)
/* ... snip ... */
dst := C.CString("black_and_white_painting.jpg")
defer C.free(unsafe.Pointer(dst))
x := 0 // <- perhaps var x int ?
C.ccv_write(image.image, dst, (*C.int)(&x), C.CCV_IO_PNG_FILE, 0)
}
Run Code Online (Sandbox Code Playgroud)
上面的示例生成以下编译时错误: cannot convert &x (type *int) to type *_Ctype_int
关于如何传递正确论点的任何想法?
我按照本教程
用C编写这段代码:
#define Py_LIMITED_API
#include <Python.h>
PyObject * startVM(PyObject *, PyObject *);
int PyArg_ParseTuple_S(PyObject * args, char* a) {
return PyArg_ParseTuple(args, "s", &a);
}
static PyMethodDef FooMethods[] = {
{"startVM", startVM, METH_VARARGS, "Starts."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef foomodule = {
PyModuleDef_HEAD_INIT, "foo", NULL, -1, FooMethods
};
PyMODINIT_FUNC PyInit_foo(void) {
return PyModule_Create(&foomodule);
}
Run Code Online (Sandbox Code Playgroud)
和此代码在GO中:
package main
import "fmt"
// #cgo pkg-config: python3
// #define Py_LIMITED_API
// #include <Python.h>
// int PyArg_ParseTuple_S(PyObject *,char *);
import "C"
//export …Run Code Online (Sandbox Code Playgroud) 是否可以在Go中获取函数引用的地址?
就像是
func myFunction() {
}
// ...
unsafe.Pointer(&myFunction)
Run Code Online (Sandbox Code Playgroud)
只是那是行不通的。我的猜测是不可能的,但是我还没有找到任何证据。
编辑:背景
我的问题的背景来自于处理CGO和C函数指针。这有效:
/*
void go_myFunction();
typedef void (*myFunction_f)();
myFunction_f pMyFunction;
*/
import "C"
//export go_myFunction
func go_myFunction() {
// ...
}
func SetupFp() {
C.pMyFunction = (*[0]byte)(unsafe.Pointer(C.go_myFunction))
}
Run Code Online (Sandbox Code Playgroud)
我也知道文档说明将指针传递给go函数不起作用。但是上面的代码似乎离它没有那么远。我只是想知道是否可以以某种方式跳过导出步骤。
我正在编写一些导出类似函数的代码:
package main
import "C"
//export returnString
func returnString() string {
//
gostring := "hello world"
return gostring
}
func main() {}
Run Code Online (Sandbox Code Playgroud)
我使用go build -buildmode = c-shared构建.so和头文件,但是当我在我的C代码中调用returnString()时,我得到"恐慌:运行时错误:cgo结果有Go指针"
在1.9中有没有办法解决这个问题?
我正在尝试使用同一目录中的单独C源文件创建一个CGO程序。如官方Cgo文档中所述,Cgo将在同一目录中编译所有C文件,但在这种情况下,它不会编译C文件。后来给出了链接器错误。
myTest.go
package main
/*
#include <stdlib.h>
#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)
}
Run Code Online (Sandbox Code Playgroud)
myTest.h
void print_str(char *s);
Run Code Online (Sandbox Code Playgroud)
myTest.c
#include "stdio.h"
void print_str(char *s)
{
printf("%s\n", s?s:"nil");
}
Run Code Online (Sandbox Code Playgroud)
编译时,出现以下错误:
> go build myTest.go
# command-line-arguments
/tmp/go-build989557946/b001/_x002.o: In function `_cgo_4c80c9e4eaf0_Cfunc_print_str':
/tmp/go-build/cgo-gcc-prolog:49: undefined reference to `print_str'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
Go版本是:
> go version
go version go1.10 linux/amd64
Run Code Online (Sandbox Code Playgroud)