Я пытаюсь создать COM-объект с нестандартным интерфейсом. Я использовал 2 метода: а) создание объекта напрямую, б) вызов QueryInterface, но я получил тот же результат.
Я использую библиотеку go -ole, но я развертываю код из функции, чтобы получить больше информации о внутренней структуре этой функции ...
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
assert.NoError(t, err)
После инициализации я пытался получить COM-объект (IDispatch) напрямую
fmt.Printf("Method 1\n\n")
makeInt := IID_IServiceFields
makeInt - объект, что мне нужно
fields := &ole.IDispatch{}
hr, _, _ := procCoCreateInstance.Call(
uintptr(unsafe.Pointer(ole.NewGUID(CLASS_DataCenterLicense))),
uintptr(0),
ole.CLSCTX_INPROC,
uintptr(unsafe.Pointer(makeInt)),
uintptr(unsafe.Pointer(&fields)))
if hr != 0 {
err = ole.NewError(hr)
}
assert.NoError(t, err)
procCoCreateInstance - CoCreateInstance от ole32.dll
Затем я пытаюсь получить тип GUID из IDispatch
ti := &ole.ITypeInfo{}
vtbl := fields.VTable()
getTypeInfo := vtbl.GetTypeInfo
hr, _, _ = syscall.Syscall6(
getTypeInfo,
4,
uintptr(unsafe.Pointer(fields)),
uintptr(0),
uintptr(ole.GetUserDefaultLCID()),
uintptr(unsafe.Pointer(&ti)),
0,
0)
if hr != 0 {
err = ole.NewError(hr)
}
assert.NoError(t, err)
ta, err := ti.GetTypeAttr()
assert.NoError(t, err)
fmt.Printf("Need: %v\n", makeInt)
fmt.Printf(" Got: %v\n", ta.Guid.String())
Итак ... Я пытаюсь получить COM-объект косвенно с помощью IUnknown
fmt.Printf("\n\nMethod 2\n\n")
unk := &ole.IUnknown{}
hr, _, _ = procCoCreateInstance.Call(
uintptr(unsafe.Pointer(ole.NewGUID(CLASS_DataCenterLicense))),
uintptr(0),
ole.CLSCTX_INPROC,
uintptr(unsafe.Pointer(ole.IID_IUnknown)),
uintptr(unsafe.Pointer(&unk)))
if hr != 0 {
err = ole.NewError(hr)
}
assert.NoError(t, err)
, а затем я пытаюсь использовать IUnknown.QueryInterface
fields = &ole.IDispatch{}
hr, _, _ = syscall.Syscall(
unk.VTable().QueryInterface,
3,
uintptr(unsafe.Pointer(unk)),
uintptr(unsafe.Pointer(makeInt)),
uintptr(unsafe.Pointer(&fields)))
if hr != 0 {
err = ole.NewError(hr)
}
и проверить информацию о типе
ti = &ole.ITypeInfo{}
vtbl = fields.VTable()
getTypeInfo = vtbl.GetTypeInfo
hr, _, _ = syscall.Syscall6(
getTypeInfo,
4,
uintptr(unsafe.Pointer(fields)),
uintptr(0),
uintptr(ole.GetUserDefaultLCID()),
uintptr(unsafe.Pointer(&ti)),
0,
0)
if hr != 0 {
err = ole.NewError(hr)
}
assert.NoError(t, err)
ta, err = ti.GetTypeAttr()
assert.NoError(t, err)
fmt.Printf("Need: %v\n", makeInt)
fmt.Printf(" Got: %v\n", ta.Guid.String())
Результаты:
Method 1
Need: {4AC461D2-CC82-4810-A352-1626C7E978DD}
Got: {31A38EBD-2346-4A5B-A10E-044DC9737D07}
Method 2
Need: {4AC461D2-CC82-4810-A352-1626C7E978DD}
Got: {31A38EBD-2346-4A5B-A10E-044DC9737D07}
Что я делаю не так?
Tnx!