func SysFreeString(v *int16) (err error) {
	hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v)))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
SysFreeString frees string system memory. This must be called with SysAllocString.
package ole
import (
	"syscall"
	"unicode/utf16"
	"unsafe"
)
var (
	procCoInitialize            = modole32.NewProc("CoInitialize")
	procCoInitializeEx          = modole32.NewProc("CoInitializeEx")
	procCoUninitialize          = modole32.NewProc("CoUninitialize")
	procCoCreateInstance        = modole32.NewProc("CoCreateInstance")
	procCoTaskMemFree           = modole32.NewProc("CoTaskMemFree")
	procCLSIDFromProgID         = modole32.NewProc("CLSIDFromProgID")
	procCLSIDFromString         = modole32.NewProc("CLSIDFromString")
	procStringFromCLSID         = modole32.NewProc("StringFromCLSID")
	procStringFromIID           = modole32.NewProc("StringFromIID")
	procIIDFromString           = modole32.NewProc("IIDFromString")
	procCoGetObject             = modole32.NewProc("CoGetObject")
	procGetUserDefaultLCID      = modkernel32.NewProc("GetUserDefaultLCID")
	procCopyMemory              = modkernel32.NewProc("RtlMoveMemory")
	procVariantInit             = modoleaut32.NewProc("VariantInit")
	procVariantClear            = modoleaut32.NewProc("VariantClear")
	procVariantTimeToSystemTime = modoleaut32.NewProc("VariantTimeToSystemTime")
	procSysAllocString          = modoleaut32.NewProc("SysAllocString")
	procSysAllocStringLen       = modoleaut32.NewProc("SysAllocStringLen")
	procSysFreeString           = modoleaut32.NewProc("SysFreeString")
	procSysStringLen            = modoleaut32.NewProc("SysStringLen")
	procCreateDispTypeInfo      = modoleaut32.NewProc("CreateDispTypeInfo")
	procCreateStdDispatch       = modoleaut32.NewProc("CreateStdDispatch")
	procGetActiveObject         = modoleaut32.NewProc("GetActiveObject")
	procGetMessageW      = moduser32.NewProc("GetMessageW")
	procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
)
func coInitialize() (err error) {
	hr, _, _ := procCoInitialize.Call(uintptr(0))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
func coInitializeEx(coinit uint32) (err error) {
	hr, _, _ := procCoInitializeEx.Call(uintptr(0), uintptr(coinit))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
func CoInitialize(p uintptr) (err error) {
	p = uintptr(0)
	return coInitialize()
}
func CoInitializeEx(p uintptr, coinit uint32) (err error) {
	p = uintptr(0)
	return coInitializeEx(coinit)
}
func CoUninitialize() {
	procCoUninitialize.Call()
}
func CoTaskMemFree(memptr uintptr) {
	procCoTaskMemFree.Call(memptr)
}
func CLSIDFromProgID(progId string) (clsid *GUID, err error) {
	var guid GUID
	lpszProgID := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId)))
	hr, _, _ := procCLSIDFromProgID.Call(lpszProgID, uintptr(unsafe.Pointer(&guid)))
	if hr != 0 {
		err = NewError(hr)
	}
	clsid = &guid
	return
}
func CLSIDFromString(str string) (clsid *GUID, err error) {
	var guid GUID
	lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str)))
	hr, _, _ := procCLSIDFromString.Call(lpsz, uintptr(unsafe.Pointer(&guid)))
	if hr != 0 {
		err = NewError(hr)
	}
	clsid = &guid
	return
}
func StringFromCLSID(clsid *GUID) (str string, err error) {
	var p *uint16
	hr, _, _ := procStringFromCLSID.Call(uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(&p)))
	if hr != 0 {
		err = NewError(hr)
	}
	str = LpOleStrToString(p)
	return
}
func IIDFromString(progId string) (clsid *GUID, err error) {
	var guid GUID
	lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId)))
	hr, _, _ := procIIDFromString.Call(lpsz, uintptr(unsafe.Pointer(&guid)))
	if hr != 0 {
		err = NewError(hr)
	}
	clsid = &guid
	return
}
func StringFromIID(iid *GUID) (str string, err error) {
	var p *uint16
	hr, _, _ := procStringFromIID.Call(uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(&p)))
	if hr != 0 {
		err = NewError(hr)
	}
	str = LpOleStrToString(p)
	return
}
func CreateInstance(clsid *GUID, iid *GUID) (unk *IUnknown, err error) {
	if iid == nil {
		iid = IID_IUnknown
	}
	hr, _, _ := procCoCreateInstance.Call(
		uintptr(unsafe.Pointer(clsid)),
		0,
		CLSCTX_SERVER,
		uintptr(unsafe.Pointer(iid)),
		uintptr(unsafe.Pointer(&unk)))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) {
	if iid == nil {
		iid = IID_IUnknown
	}
	hr, _, _ := procGetActiveObject.Call(
		uintptr(unsafe.Pointer(clsid)),
		uintptr(unsafe.Pointer(iid)),
		uintptr(unsafe.Pointer(&unk)))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
type BindOpts struct {
	CbStruct          uint32
	GrfFlags          uint32
	GrfMode           uint32
	TickCountDeadline uint32
}
func GetObject(programID string, bindOpts *BindOpts, iid *GUID) (unk *IUnknown, err error) {
	if bindOpts != nil {
		bindOpts.CbStruct = uint32(unsafe.Sizeof(BindOpts{}))
	}
	if iid == nil {
		iid = IID_IUnknown
	}
	hr, _, _ := procCoGetObject.Call(
		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(programID))),
		uintptr(unsafe.Pointer(bindOpts)),
		uintptr(unsafe.Pointer(iid)),
		uintptr(unsafe.Pointer(&unk)))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
func VariantInit(v *VARIANT) (err error) {
	hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
func VariantClear(v *VARIANT) (err error) {
	hr, _, _ := procVariantClear.Call(uintptr(unsafe.Pointer(v)))
	if hr != 0 {
		err = NewError(hr)
	}
	return
}
func SysAllocString(v string) (ss *int16) {
	pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))))
	ss = (*int16)(unsafe.Pointer(pss))
	return
}
func SysAllocStringLen(v string) (ss *int16) {
	utf16 := utf16.Encode([]rune(v + "\x00"))
	ptr := &utf16[0]
	pss, _, _ := procSysAllocStringLen.Call(uintptr(unsafe.Pointer(ptr)), uintptr(len(utf16)-1))
	ss = (*int16)(unsafe.Pointer(pss))
	return
}