[CGO] How can I convert GoString to wchar_t?

1,082 views
Skip to first unread message

Sean

unread,
Sep 26, 2020, 2:40:34 PM9/26/20
to golang-nuts

Hi gophers,

I'm trying to write the Golang wrapper for a dll with CGO.

A wrapper that will only work in windows.

I need to be able to send UTF-8 or unicode strings to c.

This issue was never asked on platforms like stackoverflow.

So I couldn't find a solution.

https://github.com/dkager/tolk/blob/master/src/Tolk.h#l72
line 72

https://github.com/dkager/tolk/blob/master/src/Tolk.h#l100
line 100

I am adding the code I tried below:


package talker

//#cgo windows  CFLAGS: -DGO_WINDOWS -Iinclude
//#cgo windows  LDFLAGS: -Llib/x64 -lTolk
//#include "Tolk.h"
import "C"
//  import "unsafe"


func Load() {
    C.Tolk_Load()
}

func IsLoaded() bool {
    if C.Tolk_IsLoaded() == false {
        return false
        }
    return true
}


func Unload() {
    C.Tolk_Unload()
}


// problem: the function I can't find a solution for.
func DetectScreenReader() string{
    return C.GoString(C.Tolk_DetectScreenReader())
}

func HasBraille() bool{
    b := C.Tolk_HasBraille()
    if (b == false) {
        return false }
    return true
}

// problem: the second function I can't find a solution for ..
func Output(text string, interrupt bool) {
    b := C.bool(bool)
    C.Tolk_Output((*C.wchar_t)(text), b)
}



error: .\talker.go:39:28: cannot convert text (type string) to type *_Ctype_ushort


Sean

👨‍🦯 I’m a software developer. I coding often Python, sometimes Go and rarely (C)/C++.

Raffaele Sena

unread,
Sep 26, 2020, 4:01:50 PM9/26/20
to Sean, golang-nuts
wchar_t is a 16 bits value representing a UTF16 character so you could convert Go strings to and from UTF16 using the unicode/utf16 package.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/aeaba06b-bb41-3e3a-3ee4-7993b8bb4596%40gmail.com.

Jan Mercl

unread,
Sep 26, 2020, 4:09:25 PM9/26/20
to Raffaele Sena, Sean, golang-nuts
On Sat, Sep 26, 2020 at 10:01 PM Raffaele Sena <raf...@gmail.com> wrote:
>
> wchar_t is a 16 bits value representing a UTF16 character so you could convert Go strings to and from UTF16 using the unicode/utf16 package.

FTR: Correct for Windows, may be different on other platforms.

peterGo

unread,
Sep 27, 2020, 4:35:26 PM9/27/20
to golang-nuts
Sean,

Go strings are UTF-8 encoded. Windows Unicode strings are UTF-16 encoded and null-terminated. The Go Windows port uses the Win32API DLLs for OS services. It has much of the code you need.

Here is a working (Windows 10, MinGW64) demonstration program which provides Tolk and UTF16 wrappers. On Windows, wchar_t is equivalent to uint16_t. Copy the linked Go Playground code and run it on your Windows machine.


Here are the Tolk and UTF16 wrappers:

func WCharPtrToString(p *C.wchar_t) string {
    return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(p)))
}

func WCharPtrFromString(s string) (*C.wchar_t, error) {
    p, err := windows.UTF16PtrFromString(s)
    return (*C.wchar_t)(unsafe.Pointer(p)), err
}

func TolkDetectScreenReader() string {
    return WCharPtrToString(C.Tolk_DetectScreenReader())
}

func TolkOutput(str string, interrupt bool) (bool, error) {
    pstr, err := WCharPtrFromString("xyzχψω")
    if err != nil {
        return false, err
    }
    rc := C.Tolk_Output(pstr, C.bool(interrupt))
    return bool(rc), nil
}

Peter

peterGo

unread,
Sep 27, 2020, 10:18:34 PM9/27/20
to golang-nuts
Sean,

Some fixes and improvements.

Copy the demonstration program code and run on a Windows machine.


Here are the Tolk and UTF16 wrappers:

func WCharPtrToString(p *C.wchar_t) string {
    return windows.UTF16PtrToString((*uint16)(p))

}

func WCharPtrFromString(s string) (*C.wchar_t, error) {
    p, err := windows.UTF16PtrFromString(s)
    return (*C.wchar_t)(p), err

}

func TolkDetectScreenReader() string {
    return WCharPtrToString(C.Tolk_DetectScreenReader())
}

func TolkOutput(str string, interrupt bool) (bool, error) {
    pstr, err := WCharPtrFromString(str)

    if err != nil {
        return false, err
    }
    ok := C.Tolk_Output(pstr, C.bool(interrupt))
    return bool(ok), nil
}

Peter
Reply all
Reply to author
Forward
0 new messages