在 C 函数中更改 golang C.String 变量的值
Change value of golang C.String variable in C function
我想从 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))
}
几乎成功了。
Output is: 1234567
但应该是:1234567890abcd
我认为传递给 C 函数的 C.String 的大小是 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))
}
经过研究我找到了解决方案:
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 函数接收 'string',我必须创建一个切片:
buf := make([]byte, 8192)
并传递一个指向它的指针:
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))
}
我想从 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))
}
几乎成功了。
Output is: 1234567
但应该是:1234567890abcd
我认为传递给 C 函数的 C.String 的大小是 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))
}
经过研究我找到了解决方案:
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 函数接收 'string',我必须创建一个切片:
buf := make([]byte, 8192)
并传递一个指向它的指针:
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))
}