多亏了cgo,我试图在C程序中使用一些Go代码
我的Go文件如下所示:
package hello
import (
"C"
)
//export HelloWorld
func HelloWorld() string{
return"Hello World"
}
而我的C代码是这样的:
#include"_obj/_cgo_export.h"
#include
int main ()
{
GoString greeting = HelloWorld();
printf("Greeting message: %s
", greeting.p );
return 0;
}
但是我得到的输出不是我期望的:
Greeting message: ?
我猜这是一个编码问题,但是关于它的文档很少,我几乎不了解C。
您知道该代码出了什么问题吗?
编辑:
正如我在下面的评论中所说:
I [...] tried to return and print just an Go int (which is a C"long
long") and got a wrong value too.
So it seems my problem is not with string encoding or null termination
but probably with how I compile the whole thing
我将尽快添加所有编译步骤
看起来Go字符串不是NUL终止的。 结构中可能有长度,您必须memcpy()到缓冲区并自己附加\0吗? 还是有一个转换功能呢?
确实有一个长度,GoString被定义为" typedef struct {char * p; GoInt n;} GoString;" 虐待尝试这种方式挖,谢谢
write(STDOUT_FILENO, greeting.p, n)应该做的工作(如果您不想memcpy缓冲区)。
printf需要NUL终止的字符串,但是Go字符串不是NUL终止的,因此您的C程序表现出未定义的行为。 而是执行以下操作:
#include"_obj/_cgo_export.h"
#include
#include
#include
int main() {
GoString greeting = HelloWorld();
char* cGreeting = malloc(greeting.n + 1);
if (!cGreeting) { /* handle allocation failure */ }
memcpy(cGreeting, greeting.p, greeting.n);
cGreeting[greeting.n] = '\0';
printf("Greeting message: %s
", cGreeting);
free(cGreeting);
return 0;
}
要么:
#include"_obj/_cgo_export.h"
#include
int main() {
GoString greeting = HelloWorld();
printf("Greeting message:");
fwrite(greeting.p, 1, greeting.n, stdout);
printf("
");
return 0;
}
或者,当然:
func HelloWorld() string {
return"Hello World\x00"
}
嗨! 感谢您的回答。 我尝试了所有代码示例,但均未成功。 然后,我尝试返回并仅打印Go int(它是C" long long"),并且也得到了错误的值。 所以看来我的问题不是字符串编码或null终止,而是我如何编译整个内容
我的问题已通过以下注释很好地描述了:从C调用go函数
You can call Go code from C, but at the moment you can't embed the Go
runtime into a C app, which is an important, but subtle, difference.
那就是我试图做的,这就是为什么它惨败的原因。
现在,我将研究新的-buildmode=c-shared选项