谁来解释一下Go指针的魔力我试着调用COM函数
func (p *IServer) Authorize(user, pass string) error {
UserName := ole.SysAllocString(login.UserName)
defer ole.SysFreeString(UserName)
UserPsw := ole.SysAllocString(login.UserPsw)
defer ole.SysFreeString(UserPsw)
// HRESULT IServer::Authorize([in] BSTR UserName, [in] BSTR UserPsw, [out] VARIANT* SID, [out, retval] long* Result)
hr, _, _ := Call(p.VTable().Authorize,
uintptr(unsafe.Pointer(p)),
uintptr(unsafe.Pointer(UserName)),
uintptr(unsafe.Pointer(UserPsw)),
uintptr(unsafe.Pointer(sid)),
uintptr(unsafe.Pointer(&res)))
...
}这段代码运行良好,但当我将转换替换为
UserName := syscall.StringToUTF16Ptr(login.UserName)
UserPsw := syscall.StringToUTF16Ptr(login.UserPsw)它会导致访问冲突!来源: go-ole
func SysAllocString(v string) (ss *int16) {
pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))))
ss = (*int16)(unsafe.Pointer(pss))
return
}我做错了什么?
更新:在C/C++ wchar*中,指针在386/amd64中都能正常工作
void Authorize(IServer* p wchar* user, wchar* pass) {
p.Authorize(user, pass ....
}发布于 2020-02-15 04:35:41
SysAllocString返回BSTR类型,即com类型对象。
typedef struct {
#ifdef _WIN64
DWORD pad;
#endif
DWORD size;
union {
char ptr[1];
WCHAR str[1];
DWORD dwptr[1];
} u; // take it as a starting point of the string
} bstr_t;换句话说,它是相同的utf16编码字符串,但是前缀的形式是它的大小( Unicode字符的长度乘以wchar_t的大小(2-4字节))。出于优化的原因,它也有填充。
由于它的浮动大小,最好使用ole包,而不是重复发明轮子。如果您想自己实现它,并且wchar_t的大小为int16 (2字节),那么您必须执行以下操作:
(半个伪代码,我没有测试它)
type BSTR *uint16
func SysAllocString(str string) (result BSTR) {
// DWORD == int32 == rune
const padf = "\x00" // only for 64 bit system
const sizef = "\x00"
// int32 == 4 byte
// int16 == 2 byte
const wordSize = unsafe.Sizeof(int16(0))
utf16 := utf16.Encode([]rune(padf + sizef + str))
/* pad is on index 0 and 1 */
size := &utf16[2 /* 0 for 32 bit system */]
// set "size" field as unicode charachers length multypled by size of wchar_t
*(*rune)(unsafe.Pointer(size)) = rune((len(utf16)-2) * int(wordSize))
result = BSTR(&utf16[0])
return
}
// ...
bstr := SysAllocString(login.UserName)
uintptr(unsafe.Pointer(bstr))https://stackoverflow.com/questions/60226011
复制相似问题