我希望将[32]C.wchar_t
转换为go字符串。
数组在我正在谈论的dll
中定义如下:
typedef struct myStruct {
WCHAR someString[32];
}
我按照以下方式定义结构:
type myStruct struct {
someString [32]C.wchar_t
}
我在dll
:
DLLINTERFACE HRESULT __stdcall GetMyStruct (myStruct* ptrMyStruct);
此方法将填充someString
的{{1}}字段。
我正在调用这样的方法(这是正常的,我认为,我无法看到myStruct
的内容):
someString
我需要将func getMyStruct() (*myStruct, uintptr) {
var getMyStruct = dll.MustFindProc("GetMyStruct")
var args = new(myStruct)
ret, _, _ := getMyStruct .Call(uintptr(unsafe.Pointer(args)))
fmt.Printf("Return: %d\n", (int)(ret))
return args, ret
}
转换为go字符串。我已尝试使用someString
,但它没有将"github.com/GeertJohan/cgo.wchar"
转换为字符串的方法。
目前我不确定我的go结构是否正确。我还不确定在将[]C.whar_t
发送到dll之前是否正确初始化{。}}。
非常感谢任何帮助。
答案 0 :(得分:1)
在Windows上,wchar_t
通常为UTF-16(little-endian)。它们通常不以BOM开头(因为它存在,因此解码器可以检测它们是以大端还是小端形式存储)。
有一个utf16套餐,但这只会翻译单个符文。但是,还有一个额外的unicode文本编码包可以提供帮助。
您可能会这样做:
dec:=unicode.UTF16(unicode.LittleEndian,unicode.UseBOM).NewDecoder()
out,err:= dec.Bytes(([]byte)(unsafe.Pointer(args.someString)))
if err!=nil {
//handle error
}
// Strings are null terminated, only want content up to null byte
i:=bytes.IndexByte(out,0)
if i==-1 {
i = len(out)
}
s:=string(out[:i])
但是,我很想将someString
声明为[64]byte
,这是一个32字符(16个字符=每个字符2个字节)所需的字节数。这样可以避免不安全的类型转换,但除此之外应该如上所述。
我正在做这件事,所以上面的代码就是一个例子&可能不一定有效 - 使用危险: - )
答案 1 :(得分:0)
似乎GeertJohan的库尚未针对最近的cgo更改进行更新,但是fork有,请尝试github.com/vitaminwater/cgo.wchar(godoc)。
如果C函数写入C类型,则传递C类型的变量。
一个(狡猾的)例子:
package main
/*
#include <wchar.h>
#include <string.h>
typedef struct myStruct {
wchar_t someString[32];
} myStruct;
wchar_t sample[6] = {0x0048, 0x0069, 0x0020, 0x4e16, 0x754c, 0};
void writeSample(myStruct *m) {
memcpy(m->someString, &sample, sizeof(wchar_t) * 6);
}
*/
import "C"
import (
"fmt"
"log"
"unsafe"
"github.com/vitaminwater/cgo.wchar"
)
func main() {
m := C.myStruct{}
C.writeSample(&m)
s, err := wchar.WcharStringPtrToGoString(unsafe.Pointer(&m.someString))
if err != nil {
log.Fatal(err)
}
fmt.Println(s)
}
输出:
Hi 世界