如何在 Go 和 Swig 中使用 LPCWSTR?
How to use LPCWSTR with Go and Swig?
我正在尝试使用 Swig 将 C 库与 Go 结合使用。这是简化的代码,我知道我可以使用 cgo 但我需要使用带 LPCWSTR 参数的函数和 Swig。
我在 https://github.com/AllenDang/w32/blob/c92a5d7c8fed59d96a94905c1a4070fdb79478c9/typedef.go 上看到 LPCWSTR
相当于 *uint16
所以 syscall.UTF16PtrFromString()
似乎是我需要的,但是当我 运行代码。
我想知道我是否应该使用 SwigcptrLPCWSTR
。
libtest.c
#include <windows.h>
#include <stdio.h>
#include "libtest.h"
__stdcall void hello(const LPCWSTR s)
{
printf("hello: %ls\n", s);
}
libtest.h
#ifndef EXAMPLE_DLL_H
#define EXAMPLE_DLL_H
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_EXAMPLE_DLL
#define EXAMPLE_DLL __declspec(dllexport)
#else
#define EXAMPLE_DLL __declspec(dllimport)
#endif
void __stdcall EXAMPLE_DLL hello(const LPCWSTR s);
#ifdef __cplusplus
}
#endif
#endif
我用 :
构建库和 DLL
gcc -c -DBUILDING_EXAMPLE_DLL libtest.c
gcc -shared -o libtest.dll libtest.o -Wl,--out-implib,libtest.a
main.swig
%module main
%{
#include "libtest.h"
%}
%include "windows.i"
%include "libtest.h"
main.go
package main
import (
"syscall"
"unsafe"
)
func main() {
p, err := syscall.UTF16PtrFromString("test")
if err != nil {
panic(err)
}
Hello(SwigcptrLPCWSTR(unsafe.Pointer(p)))
}
追踪
Exception 0xc0000005 0x0 0xffffffffffffffff 0x7ffcc761f2e1
PC=0x7ffcc761f2e1
signal arrived during external code execution
main._Cfunc__wrap_hello_main_90cec49f7d68ac58(0xc082002110)
_/D_/lpcwstr/go/_obj/_cgo_gotypes.go:53 +0x38
main.Hello(0x500028, 0xc082002120)
_/D_/lpcwstr/go/_obj/main.go:63 +0x3c
main.main()
D:/lpcwstr/go/main.go:9 +0x96
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:1696 +0x1
rax 0x6c007400690074
rbx 0x6c007400690074
rcx 0x7ffffffe
rdi 0x24fd73
rsi 0x7
rbp 0x24fb00
rsp 0x24fa00
r8 0xffffffffffffffff
r9 0x7ffcc75d0000
r10 0x0
r11 0x200
r12 0xffffffff
r13 0x24fd60
r14 0x10
r15 0x6264403a
rip 0x7ffcc761f2e1
rflags 0x10202
cs 0x33
fs 0x53
gs 0x2b
我怀疑您看到的问题是因为您传递给 SWIG 的是双指针,而不仅仅是指针,即 wchar_t**
而不仅仅是 wchar_t*
.
我认为这是因为您调用 UTF16PtrFromString
获取 UTF16 字符串的地址,然后调用 unsafe.Pointer(p)
再次获取其输入地址。
来自源代码:
func UTF16PtrFromString(s string) (*uint16) {
a := UTF16FromString(s)
return &a[0]
}
所以我想如果你改为使用:
func main() {
p, err := syscall.UTF16FromString("test") // Note the subtle change here
if err != nil {
panic(err)
}
Hello(SwigcptrLPCWSTR(unsafe.Pointer(p)))
}
它应该按预期工作。
我正在尝试使用 Swig 将 C 库与 Go 结合使用。这是简化的代码,我知道我可以使用 cgo 但我需要使用带 LPCWSTR 参数的函数和 Swig。
我在 https://github.com/AllenDang/w32/blob/c92a5d7c8fed59d96a94905c1a4070fdb79478c9/typedef.go 上看到 LPCWSTR
相当于 *uint16
所以 syscall.UTF16PtrFromString()
似乎是我需要的,但是当我 运行代码。
我想知道我是否应该使用 SwigcptrLPCWSTR
。
libtest.c
#include <windows.h>
#include <stdio.h>
#include "libtest.h"
__stdcall void hello(const LPCWSTR s)
{
printf("hello: %ls\n", s);
}
libtest.h
#ifndef EXAMPLE_DLL_H
#define EXAMPLE_DLL_H
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_EXAMPLE_DLL
#define EXAMPLE_DLL __declspec(dllexport)
#else
#define EXAMPLE_DLL __declspec(dllimport)
#endif
void __stdcall EXAMPLE_DLL hello(const LPCWSTR s);
#ifdef __cplusplus
}
#endif
#endif
我用 :
构建库和 DLLgcc -c -DBUILDING_EXAMPLE_DLL libtest.c
gcc -shared -o libtest.dll libtest.o -Wl,--out-implib,libtest.a
main.swig
%module main
%{
#include "libtest.h"
%}
%include "windows.i"
%include "libtest.h"
main.go
package main
import (
"syscall"
"unsafe"
)
func main() {
p, err := syscall.UTF16PtrFromString("test")
if err != nil {
panic(err)
}
Hello(SwigcptrLPCWSTR(unsafe.Pointer(p)))
}
追踪
Exception 0xc0000005 0x0 0xffffffffffffffff 0x7ffcc761f2e1
PC=0x7ffcc761f2e1
signal arrived during external code execution
main._Cfunc__wrap_hello_main_90cec49f7d68ac58(0xc082002110)
_/D_/lpcwstr/go/_obj/_cgo_gotypes.go:53 +0x38
main.Hello(0x500028, 0xc082002120)
_/D_/lpcwstr/go/_obj/main.go:63 +0x3c
main.main()
D:/lpcwstr/go/main.go:9 +0x96
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:1696 +0x1
rax 0x6c007400690074
rbx 0x6c007400690074
rcx 0x7ffffffe
rdi 0x24fd73
rsi 0x7
rbp 0x24fb00
rsp 0x24fa00
r8 0xffffffffffffffff
r9 0x7ffcc75d0000
r10 0x0
r11 0x200
r12 0xffffffff
r13 0x24fd60
r14 0x10
r15 0x6264403a
rip 0x7ffcc761f2e1
rflags 0x10202
cs 0x33
fs 0x53
gs 0x2b
我怀疑您看到的问题是因为您传递给 SWIG 的是双指针,而不仅仅是指针,即 wchar_t**
而不仅仅是 wchar_t*
.
我认为这是因为您调用 UTF16PtrFromString
获取 UTF16 字符串的地址,然后调用 unsafe.Pointer(p)
再次获取其输入地址。
来自源代码:
func UTF16PtrFromString(s string) (*uint16) {
a := UTF16FromString(s)
return &a[0]
}
所以我想如果你改为使用:
func main() {
p, err := syscall.UTF16FromString("test") // Note the subtle change here
if err != nil {
panic(err)
}
Hello(SwigcptrLPCWSTR(unsafe.Pointer(p)))
}
它应该按预期工作。