예제 #1
0
파일: client.go 프로젝트: jmptrader/types
func Invoke(obj interface{}, method uintptr, displayID DisplayID, dispatchContext DispatchContext, params ...interface{}) (result *com.Variant, err error) {
	var displayParams com.DisplayParameter
	var vargs []com.Variant

	if dispatchContext&com.PropertySetDispatchContext != 0 {
		displayNames := [1]int32{com.PropertySetDisplayID}
		displayParams.NamedArgs = uintptr(unsafe.Pointer(&displayNames[0]))
		displayParams.NamedArgsLength = 1
	}

	if len(params) > 0 {
		vargs = make([]com.Variant, len(params))
		for i, v := range params {
			//n := len(params)-i-1
			n := len(params) - i - 1
			vargs[n] = com.VariantByValueType(v)
			// This should clear all variant types.
			defer com.VariantClear(vargs[n])
		}
		displayParams.Args = uintptr(unsafe.Pointer(&vargs[0]))
		displayParams.ArgsLength = uint32(len(params))
	}

	result = new(com.Variant)
	var excepInfo EXCEPINFO
	com.VariantInit(result)
	hr, _, _ := syscall.Syscall9(
		method,
		uintptr(9),
		uintptr(unsafe.Pointer(obj)),
		uintptr(displayID),
		uintptr(unsafe.Pointer(com.NullInterfaceID)),
		uintptr(com.GetDefaultUserLocaleID()),
		uintptr(dispatchContext),
		uintptr(unsafe.Pointer(&displayParams)),
		uintptr(unsafe.Pointer(result)),
		uintptr(unsafe.Pointer(&excepInfo)),
		uintptr(0))
	if hr != 0 {
		err = NewErrorWithSubError(hr, BstrToString(excepInfo.bstrDescription), excepInfo)
	}
	/*
		// This is now deferred and should clear all variants.
		for _, varg := range vargs {
			// This should clear all variant types.
			com.VariantClear(varg)
			if varg.VariantType == BinaryStringVariantType && varg.Val != 0 {
				SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val)))))
			}
			/*
			if varg.VariantType == (BinaryStringVariantType|ByReferenceVariantType) && varg.Val != 0 {
				*(params[n].(*string)) = LpOleStrToString((*uint16)(unsafe.Pointer(uintptr(varg.Val))))
				println(*(params[n].(*string)))
				fmt.Fprintln(os.Stderr, *(params[n].(*string)))
			}
			//* /
		}
	*/
	return
}
예제 #2
0
func Example_winsock() {
	queryInterface := func(self *interface{}, interfaceID *com.GUID, client **interface{}) uint32 {
		code := iunknown.QueryInterfaceService(self, interfaceID, *client)
		if code == com.NoInterfaceErrorCode {
			s := com.StringFromClassID(interfaceID)
			if s == "{248DD893-BB45-11CF-9ABC-0080C7E7B78D}" {
				iunknown.AddRefService(self)
				*client = self
				return com.SuccessResponseCode
			}
		}
		return com.NoInterfaceErrorCode
	}

	getIDsOfNames := func(this *iunknown.IUnknown, iid *com.GUID, wnames []*uint16, namelen int, lcid int, pdisp []int32) uintptr {
		for n := 0; n < namelen; n++ {
			pdisp[n] = int32(n)
		}
		return uintptr(com.SuccessResponseCode)
	}

	invoke := func(this *IDispatch, dispid int32, riid *com.GUID, lcid int, flags int16, dispparams *com.DISPPARAMS, result *com.Variant, pexcepinfo *com.EXCEPINFO, nerr *uint) {
		switch dispid {
		case 0:
			log.Println("DataArrival")
			winsock := (*com.EventReceiver)(unsafe.Pointer(this)).host
			var data com.Variant
			com.VariantInit(&data)
			CallMethod(winsock, "GetData", &data)
			s := string(data.ToArray().ToByteArray())
			println()
			println(s)
			println()
		case 1:
			log.Println("Connected")
			winsock := (*com.EventReceiver)(unsafe.Pointer(this)).host
			oleutil.CallMethod(winsock, "SendData", "GET / HTTP/1.0\r\n\r\n")
		case 3:
			log.Println("SendProgress")
		case 4:
			log.Println("SendComplete")
		case 5:
			log.Println("Close")
			this.Release()
		case 6:
			log.Fatal("Error")
		default:
			log.Println(dispid)
		}
		return com.NotImplementedErrorCode
	}

	com.CoInitialize()
	defer com.CoUninitialize()

	var unknown *iunknown.Unknown
	var winsock *Dispatch

	err := com.CreateObject("{248DD896-BB45-11CF-9ABC-0080C7E7B78D}", &unknown)
	if err != nil {
		panic(err.Error())
	}
	unknown.QueryInterface(com.IDispatchInterfaceID, &winsock)
	defer winsock.Release()

	classID, _ := com.ClassIDFromString("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}")

	destination := &com.EventReceiver{}
	destination.VirtualTable = &VirtualTable{
		QueryInterface:   syscall.NewCallback(queryInterface),
		AddRef:           syscall.NewCallback(iunknown.AddRefService),
		Release:          syscall.NewCallback(iunknown.ReleaseService),
		GetTypeInfoCount: syscall.NewCallback(GetTypeInfoCountService),
		GetTypeInfo:      syscall.NewCallback(GetTypeInfoService),
		GetIDsOfNames:    syscall.NewCallback(getIDsOfNames),
		Invoke:           syscall.NewCallback(invoke)}
	destination.Host = winsock

	iconnectionpointcontainer.ConnectObject(winsock, classID, (*iunknown.Unknown)(unsafe.Pointer(destination)))
	_, err = CallMethod(winsock, "Connect", "127.0.0.1", 80)
	if err != nil {
		log.Fatal(err)
	}

	var m com.Msg
	for dest.ReferenceCount != 0 {
		com.GetMessage(&m, 0, 0, 0)
		com.DispatchMessage(&m)
	}
}