2017-07-27 213 views
0

我期待将[32]C.wchar_t转换为去字符串。GoLang转换C.wchar_t去字符串

阵列被定义为dll如下我说于:

typedef struct myStruct { 
    WCHAR someString[32]; 
} 

我定义中去该结构如下:

type myStruct struct { 
    someString [32]C.wchar_t 
} 

我在dll的方法:

DLLINTERFACE HRESULT __stdcall GetMyStruct (myStruct* ptrMyStruct); 

该方法将填充someString字段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 
} 

我需要someString转换为去串。我曾尝试使用"github.com/GeertJohan/cgo.wchar",但它没有将[]C.whar_t转换为字符串的方法。

目前我不确定我的结构是否正确。我也不确定在将它发送到dll之前是否正确初始化myStruct

任何帮助将不胜感激。

回答

1

在Windows上,wchar_t通常是UTF-16(小端)。它们通常不以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个字节)需要。这将避免不安全的类型转换,但是应该如上所述工作。

所以上面的代码意味着作为示例&不一定工作,我这样做了我的头顶 - 使用后果自负:-)

0

看来GeertJohan的图书馆有没有已针对最近的cgo更改进行了更新,但叉已经尝试使用github.com/vitaminwater/cgo.wchargodoc)。

如果C函数写入C类型,则传递C类型的变量。

A(躲闪)例如:

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 世界