当我尝试在Mac上编译我的包装器时,库较旧并且界面略有不同.99%的代码是相同的,只需要改变一些C调用.
在Go中处理这样的问题的最佳做法是什么?
有没有办法进行条件编译或条件导入?
是否可以使用Go来构建Android游戏?我并不喜欢主题行中提到的技术.我知道有些人在Go中构建了一些Android程序,但是他们可能已经无头了.
是否可以在cgo中混合一些C++代码?
我试过这个:
package main
/*
#include <iostream>
extern "C" void test(const char* str)
{
std::cout << str;
}
*/
// #cgo CFLAGS: -x c++
// #cgo LDFLAGS: -lstdc++
import "C"
func main() {
C.test(C.CString("Testing!!!"))
}
Run Code Online (Sandbox Code Playgroud)
但我得到这些错误:
error: 'char* CString(_GoString_)' cannot appear in a constant-exp
error: 'void test(const char*)' cannot appear in a constant-expres
error: invalid conversion from 'char* (*)(_GoString_)' to 'long long int' [-fpermissive]
error: invalid conversion from 'void (*)(const char*)' to 'long long int' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
我正在使用go1.0.2和MinGW-w64 4.7.1
我想使用以下c作为Go的cgo:
#include <X11/extensions/scrnsaver.h>
main() {
XScreenSaverInfo *info = XScreenSaverAllocInfo();
Display *display = XOpenDisplay(0);
XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
printf("%u ms\n", info->idle);
}
Run Code Online (Sandbox Code Playgroud)
建立:
gcc -o idle printXIdleTime.c -lX11 -lXss
Run Code Online (Sandbox Code Playgroud)
我重写了Go的cgo的代码:
package tools
// #cgo pkg-config: x11
// #include <X11/extensions/scrnsaver.h>
import "C"
func GetIdleTime() (idleTime uint32) {
var info *C.XScreenSaverInfo
var display *C.Display
info = C.XScreenSaverAllocInfo()
display = C.XOpenDisplay(0)
defaultRootWindow := C.XDefaultRootWindow(display)
C.XScreenSaverQueryInfo(display, defaultRootWindow, info)
idleTime = info.idle
return
}
Run Code Online (Sandbox Code Playgroud)
试图编译:
go build -gccgoflags="-lXss -lX11"
Run Code Online (Sandbox Code Playgroud)
但是我收到链接器错误:
/tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o:在函数
_cgo_c0e279f6f16e_Cfunc_XScreenSaverAllocInfo': ./x11.go:52: undefined reference toXScreenSaverAllocInfo'/tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o中:在函数 …
我正在使用cgo从Go开发库绑定.让我考虑下面的C结构和Go Struct.
struct cons_t {
size_t type;
cons_t *car;
cons_t *cdr;
};
cons_t* parse(const char *str);
Run Code Online (Sandbox Code Playgroud)
这是结构
type Cons struct {
type int;
car *Cons;
cdr *Cons;
}
Run Code Online (Sandbox Code Playgroud)
为了实现如下的Go功能,有什么更好的方法来实现TranslateCCons2GoCons?
func Parse (str string) *Cons {
str_ptr := C.CString(string);
cons_ptr := C.parse(str_ptr);
retCons := TranslateCCons2GoCons(cons_ptr);
return retCons;
}
Run Code Online (Sandbox Code Playgroud)
我的第一个答案如下.
/*#cgo
int getType(cons_t *cons) {
return cons->type;
}
cons_t *getCar(cons_t *cons) {
return cons->car;
}
cons_t *getCdr(cons_t *cons) {
return cons->cdr;
}
*/
func TranslateCCons2GoCons (c *C.cons_t) Cons {
type := C.getType(c); …Run Code Online (Sandbox Code Playgroud) 有时,C API可能需要NULL指针.
CGO有可能吗?
例如,我想strcmp()在Go语言程序中传递一个null参数:
package strutil
/*
#include <stdlib.h>
#include <string.h>
*/
import (
"C"
"unsafe"
)
func StrCmp(a, b string) int {
pca := C.CString(a)
defer C.free(pca)
pcb := C.CString(b)
defer C.free(pcb)
ret := C.strcmp(pca, pcb)
return int(ret)
}
Run Code Online (Sandbox Code Playgroud)
如果我设置pca为nil,则会发生此错误:
Exception 0xc0000005 0x0 0x0 0x76828b21
PC=0x76828b21
signal arrived during cgo execution
strutil._Cfunc_strcmp(0x0, 0x761b00, 0x0)
strutil/_obj/_cgo_gotypes.go:79 +0x49
strutil.StrCmp(0x19, 0x10, 0x4bbf38, 0xa, 0x1fbc1f98, 0x0, 0x0, 0xffff, 0x0, 0x0, ...)
Run Code Online (Sandbox Code Playgroud)
那么,我怎样才能将NULL传递给strcmp?
谢谢
我试图用Go绑定C++ OpenCV程序.我正在使用你如何使用cgo静态链接ac库的概念?[1].我的myimgcom.cpp档案是:
/**
* @file SURF_FlannMatcher
* @brief SURF detector + descriptor + FLANN Matcher
* @author A. Huaman
Edited: nnnnn
*/
#include <stdio.h>
#include <string>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/features2d.hpp"
using namespace cv;
void readme();
int mysurf( int myarg)
{
string option1= "./Lenna.png";
string option2= "./Lenna.png";
if( myarg != 3 )
{ readme(); return -1; }
std::cout << option1 << option2;
Mat img_1 = imread( option1, CV_LOAD_IMAGE_GRAYSCALE ); …Run Code Online (Sandbox Code Playgroud) 我正在使用一个 C 库,与下面不同,我无法控制它。我需要将指向也包含指针的数组的指针传递给 C 函数。
package main
/*
#include <stdio.h>
typedef int* pInt;
void foo(pInt p[]) {
printf("foo()\n");
}
*/
import "C"
import "unsafe"
func main() {
var i C.int
var p1 C.pInt = (*C.int)(unsafe.Pointer(&i))
var p2 C.pInt = (*C.int)(unsafe.Pointer(&i))
var ps []C.pInt = []C.pInt{p1, p2}
C.foo(unsafe.Pointer(&ps[0]))
}
Run Code Online (Sandbox Code Playgroud)
此代码导致错误panic: runtime error: cgo argument has Go pointer to Go pointer。我想知道如何重写此代码的 Go 部分,使其满足 Cgo 的指针规则。我希望我可以在不必编写 C 帮助程序代码的情况下做到这一点。
我cgo在一个项目中使用,我想导出一个函数供使用.这是我想要实现的一个例子:
package csplit
import (
"C"
"strings"
)
//export Split
/* The Split function takes two C strings, the second of which represents
a substring to split on, and returns an array of strings. Example:
Split("1,2", ",") // gives ["1", "2"]
*/
func Split(original *C.char, split *C.char) []*C.char {
goResult := strings.Split(C.GoString(original), C.GoString(split))
cResult := make([]*C.char, len(goResult))
for idx, substring := range goResult {
cResult[idx] = C.CString(substring)
}
return cResult
}
Run Code Online (Sandbox Code Playgroud)
问题是返回类型是Go分配数据,而不是移入C堆.这恐慌:runtime error: cgo result has Go …
我正在尝试在 MacOS 机器上编译以下代码
// #cgo darwin LDFLAGS: -L${SRCDIR}/build/darwin -lprocessing_lib
// #cgo linux LDFLAGS: -L${SRCDIR}/build/linux -lprocessing_lib
// #include "Processing-bridge.h"
// #include <stdlib.h>
import "C"
import "unsafe"
type ProcessorWrapper struct {
ptr unsafe.Pointer
}
func init() {
pr.ptr = C.NewProcessor()
}
func GetDefault() (id int, name string) {
var default = C.GetDefault(pr.ptr)
id = int(default.materialId)
name = C.GoString(default.name)
return
}
Run Code Online (Sandbox Code Playgroud)
我在 LDFLAGS 中定义的正确位置有 libprocessing_lib.so 文件。但是编译器仍然抛出一个错误说
dyld: Library not loaded: build/lib_processing_lib.so
Referenced from: /Users/ag/workspace/src/github.com/apremalal/pq-processor/./pq-processor
Reason: image not found
Run Code Online (Sandbox Code Playgroud)
一旦我将 build/lib_processing_lib.so 复制到项目的根目录,它就可以工作了。
似乎 LDFLAGS …