更改C函数中golang C.字符串变量的值

更改C函数中golang C.字符串变量的值,go,cgo,Go,Cgo,我想从C函数中得到一个int和string。 int-错误代码,string-数据 这样做: package main /* #include <stdlib.h> #include <string.h> #include <stdio.h> int test(char *out){ snprintf(out, sizeof out, "1234567890abcd"); return 0; } */ import "C" import (

我想从C函数中得到一个int和string。 int-错误代码,string-数据

这样做:

package main
/*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int test(char *out){
  snprintf(out, sizeof out, "1234567890abcd");
  return 0;
}

*/
import "C"

import (
  "fmt"
  "unsafe"
)

func main() {
  foo := C.CString("")
  defer C.free(unsafe.Pointer(foo))
  C.test(foo)
  fmt.Println("Output is: "+C.GoString(foo))
}
主程序包
/*
#包括
#包括
#包括
int测试(字符*输出){
snprintf(输出,输出尺寸,“1234567890abcd”);
返回0;
}
*/
输入“C”
进口(
“fmt”
“不安全”
)
func main(){
foo:=C.CString(“”)
延迟C.free(不安全的指针(foo))
C.测试(foo)
fmt.Println(“输出为:“+C.GoString(foo))
}
它几乎成功了

输出为:1234567

但应为:1234567890abcd

我认为传递给C函数的C.字符串的大小是8。 但我不知道如何扩展它(固定大小8)或更改为动态


所以问题是:我应该如何将该变量传递给C?

您正在对指针调用函数
sizeof
。在您的计算机上,指针的大小是8字节,因此您将返回长度为8的字符串

我不知道应该如何准确地管理指针大小的所有细节,因为我不太擅长C语言,但这个例子说明了如何解决眼前的问题

package main
/*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int test(char *out){
  snprintf(out, 16, "1234567890abcd");
  return 0;
}

*/
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    foo := C.CString("")
    defer C.free(unsafe.Pointer(foo))
    C.test(foo)
    fmt.Println("Output is: "+C.GoString(foo))
}
主程序包
/*
#包括
#包括
#包括
int测试(字符*输出){
snprintf(输出,16,“1234567890abcd”);
返回0;
}
*/
输入“C”
进口(
“fmt”
“不安全”
)
func main(){
foo:=C.CString(“”)
延迟C.free(不安全的指针(foo))
C.测试(foo)
fmt.Println(“输出为:“+C.GoString(foo))
}

经过研究,我找到了一个解决方案:

package main


/*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int test(char *out, int len){
  snprintf(out, len, "1234567890123456789012345671`iknvcap9nv1-93hbf1-39b");
  return 0;

}

*/
import "C"

import (
  "fmt"
  "unsafe"
)

func main() {
  buf := make([]byte, 8192)
  C.test((*C.char)(unsafe.Pointer(&buf[0])), C.int(len(buf)))
  fmt.Println(string(buf))
}
并向其传递一个指针:

  C.test((*C.char)(unsafe.Pointer(&buf[0])), C.int(len(buf)))

在这种情况下使用C.String是不起作用的。

对于将来遇到这种情况的任何人来说,C.CString确实起作用,但不能将sizeof与指针一起使用,因为它总是8个字符。我是这样做的:

package main

/*
#include <stdlib.h>
#include <string.h>

int test(char* out){
  strcpy(out, "1234567890123456789012345671`iknvcap9nv1-93hbf1-39b");
  return 0;
}

*/
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    foo := C.CString("")
    defer C.free(unsafe.Pointer(foo))
    C.test(foo)
    fmt.Println("Output is: " + C.GoString(foo))
}
主程序包
/*
#包括
#包括
int测试(字符*输出){
strcpy(输出,“12345678900123456789012345671`iknvcap9nv1-93hbf1-39b”);
返回0;
}
*/
输入“C”
进口(
“fmt”
“不安全”
)
func main(){
foo:=C.CString(“”)
延迟C.free(不安全的指针(foo))
C.测试(foo)
fmt.Println(“输出为:“+C.GoString(foo))
}

您可能想发布您的C代码。在确定问题的确切位置时遇到困难。所有需要的C代码都在/***->函数测试中,这是我在避孕药中遇到的问题。作为参考,有一个稍微相关的问题。不幸的是,它仍然没有像预期的那样工作。当您更改snprintf(输出,16,“1234567890abcd”);输入长度超过26个字符的内容,例如:snprintf(out,30,“1234567890012345678901234567”);程序崩溃:`/tmp/go-build755328986/命令行参数/\u obj/exe/strings:free():下一个大小无效(fast):0x0000000001f99010***================================================回溯:=/lib64/libc.so.6(+0x7d053)[0x7f3fa64f2053]/tmp/go-build755328986/命令行参数/\u obj/exe/strings[0x439925]==============================内存映射:。。。
package main

/*
#include <stdlib.h>
#include <string.h>

int test(char* out){
  strcpy(out, "1234567890123456789012345671`iknvcap9nv1-93hbf1-39b");
  return 0;
}

*/
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    foo := C.CString("")
    defer C.free(unsafe.Pointer(foo))
    C.test(foo)
    fmt.Println("Output is: " + C.GoString(foo))
}