英文:
Why passing Go bytes to C, the bytes length doesn't match in cgo in this code below?
问题
将golang字节传递给C时,字节长度不匹配。
结果的strlen(key)和keylen不匹配。
使用"go build file.go"进行构建。
您可以在下面的链接中下载go文件:
https://pastebin.com/raw/hnMfXJKq
<- 有人知道为什么我的cgo调用[]bytes到c时会出错吗?为什么strlen不匹配?
预期输出应该是相同的键长度。有时有效,有时无效。
package main
/*
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
void replaceK(void *key, size_t keylen, void *value, size_t valuelen);
void replaceK(void *key, size_t keylen, void *value, size_t valuelen)
{
printf("replaceK : key = %s = %lu = %lu = %s = %lu\n",(char*) key,keylen,strlen(key),(char*) value,valuelen);
if (keylen != strlen(key)){
printf("ERROR!!! keylen : %lu != strlen(key) : %lu!!!\n",keylen,strlen(key));
exit(1);
}
}
*/
import "C"
import (
"fmt"
"unsafe"
"math/rand"
"time"
)
func Set(key,value []byte) {
cKey := cByteSlice(key)
cValue := cByteSlice(value)
C.replaceK(unsafe.Pointer(cKey),C.ulong(len(key)),unsafe.Pointer(cValue),C.ulong(len(value)))
C.free(unsafe.Pointer(cKey))
C.free(unsafe.Pointer(cValue))
}
func byteToChar(b []byte) *C.char {
var c *C.char
if len(b) > 0 {
c = (*C.char)(unsafe.Pointer(&b[0]))
}
return c
}
var letterRunes = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func RandStringRunes(n int) []byte {
randNum := rand.Intn(n)+1
b := make([]byte, randNum)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return b
}
func cByteSlice(b []byte) *C.char {
var c *C.char
if len(b) > 0 {
c = (*C.char)(C.CBytes(b))
}
return c
}
func main() {
rand.Seed(time.Now().UnixNano())
var key []byte
var value []byte
for i:=0;i<10000000;i++ {
key = RandStringRunes(10)
value = RandStringRunes(20)
randnum := 1
if randnum == 1 {
fmt.Printf(">>> = %s = %s\n",key, value)
Set(key,value)
}
}
}
英文:
When passing golang bytes to C, the bytes length doesn't match.
The resulting strlen(key) and keylen doesnt match up.
Build with "go build file.go"
You can download the go file below here:
https://pastebin.com/raw/hnMfXJKq
<- does anyone know why my cgo call the []bytes to c has error? why the strlen doesnt match?
Expected output is supposed to be the same key length. Sometimes work, sometimes doesn't.
package main
/*
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
void replaceK(void *key, size_t keylen, void *value, size_t valuelen);
void replaceK(void *key, size_t keylen, void *value, size_t valuelen)
{
printf("replaceK : key = %s = %lu = %lu = %s = %lu\n",(char*) key,keylen,strlen(key),(char*) value,valuelen);
if (keylen != strlen(key)){
printf("ERROR!!! keylen : %lu != strlen(key) : %lu!!!\n",keylen,strlen(key));
exit(1);
}
}
*/
import "C"
import (
"fmt"
"unsafe"
"math/rand"
"time"
)
func Set(key,value []byte) {
cKey := cByteSlice(key)
cValue := cByteSlice(value)
C.replaceK(unsafe.Pointer(cKey),C.ulong(len(key)),unsafe.Pointer(cValue),C.ulong(len(value)))
C.free(unsafe.Pointer(cKey))
C.free(unsafe.Pointer(cValue))
}
func byteToChar(b []byte) *C.char {
var c *C.char
if len(b) > 0 {
c = (*C.char)(unsafe.Pointer(&b[0]))
}
return c
}
var letterRunes = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func RandStringRunes(n int) []byte {
randNum := rand.Intn(n)+1
b := make([]byte, randNum)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return b
}
func cByteSlice(b []byte) *C.char {
var c *C.char
if len(b) > 0 {
c = (*C.char)(C.CBytes(b))
}
return c
}
func main() {
rand.Seed(time.Now().UnixNano())
var key []byte
var value []byte
for i:=0;i<10000000;i++ {
key = RandStringRunes(10)
value = RandStringRunes(20)
randnum := 1
if randnum == 1 {
fmt.Printf(">>> = %s = %s\n",key, value)
Set(key,value)
}
}
}
答案1
得分: 1
C的strlen
函数用于处理以空字符结尾的字符串,而不是指针+长度形式的字符串。
你可以使用C的printf
函数并使用%.*s
代替%s
来打印指针+长度形式的字符串。由于Go的string
和[]byte
变量都使用指针+长度编码,这可能是从Go获取字符串后打印的正确方式。
英文:
The C strlen
function is for use with null-terminated strings, not pointer+length strings.
You can print a pointer+length string with the C printf
function using %.*s
instead of %s
. Since Go string
and []byte
variables both use the pointer+length encoding, that is probably the right way to print a string obtained from Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论