{{if .RequiresActivation}}{{/*Activate class*/ -}}
inspectable, err := ole.RoGetActivationFactory("{{.ExclusiveTo}}", ole.NewGUID(GUID{{.FuncOwner}}))
if err != nil {
    return {{range .ReturnParams -}}
        {{.GoDefaultValue}}, {{end}}err
}
v := (*{{.FuncOwner}})(unsafe.Pointer(inspectable))

{{end -}}

{{- /* Declare out variables*/ -}}

{{range (concat .InParams .ReturnParams) -}}
    {{ if not .IsOut}}{{continue}}{{end -}}
    {{if eq .GoTypeName "string" -}}
        var {{.GoVarName}}HStr ole.HString
    {{ else -}}
        var {{.GoVarName}} {{template "variabletype.tmpl" . -}}
        {{if .Type.IsArray}} = make({{template "variabletype.tmpl" . -}}, {{.GoVarName}}Size){{end}}
    {{ end -}}
{{ end -}}

{{- /* Convert in variables to winrt types */ -}}

{{range .InParams -}}
    {{ if .IsOut}}{{continue}}{{end -}}
    {{if eq .GoTypeName "string" -}}
        {{.GoVarName}}HStr, err := ole.NewHString({{.GoVarName}})
        if err != nil{
            return {{range $.InParams}}{{if .IsOut}}{{.GoDefaultValue}}, {{end}}{{end -}}
                {{range $.ReturnParams }}{{.GoDefaultValue}}, {{end}}err
        }
    {{ end -}}
{{ end -}}
hr, _, _ := syscall.SyscallN(
    v.VTable().{{funcName .}},
    uintptr(unsafe.Pointer(v)), // this
    {{range (concat .InParams .ReturnParams) -}}
        {{if .Type.IsArray -}}
            {{/* Arrays need to pass a pointer to their first element */ -}}
            uintptr(unsafe.Pointer(&{{.GoVarName}}[0])),   // {{if .IsOut}}out{{else}}in{{end}} {{.GoTypeName}}
        {{else if .IsOut -}}
            {{if (or .Type.IsPrimitive .Type.IsEnum) -}}
                {{if eq .GoTypeName "string" -}}
                    uintptr(unsafe.Pointer(&{{.GoVarName}}HStr)),   // out {{.GoTypeName}}
                {{else -}}
                    uintptr(unsafe.Pointer(&{{.GoVarName}})),   // out {{.GoTypeName}}
                {{end -}}
            {{else -}}
                uintptr(unsafe.Pointer(&{{.GoVarName}})),   // out {{.GoTypeName}}
            {{end -}}
        {{else if .Type.IsPointer -}}
            uintptr(unsafe.Pointer({{.GoVarName}})),   // in {{.GoTypeName}}
        {{else if (or .Type.IsPrimitive .Type.IsEnum) -}}
            {{ if eq .GoTypeName "bool" -}}
                uintptr(*(*byte)(unsafe.Pointer(&{{.GoVarName}}))),   // in {{.GoTypeName}}
            {{ else if eq .GoTypeName "string" -}}
                uintptr({{.GoVarName}}HStr),   // in {{.GoTypeName}}
            {{else -}}
                uintptr({{.GoVarName}}),   // in {{.GoTypeName}}
            {{end -}}
        {{else if .Type.IsGeneric -}}
            uintptr({{.GoVarName}}),   // in {{.GoTypeName}}
        {{else -}}
            uintptr(unsafe.Pointer(&{{.GoVarName}})),   // in {{.GoTypeName}}
        {{end -}}
    {{end -}}
)

if hr != 0 {
    return {{range .InParams}}{{if .IsOut}}{{.GoDefaultValue}}, {{end}}{{end -}}
        {{range .ReturnParams }}{{.GoDefaultValue}}, {{end}}ole.NewError(hr)
}

{{range (concat .InParams .ReturnParams) -}}
    {{ if not .IsOut}}{{continue}}{{end -}}
    {{if eq .GoTypeName "string" -}}
        {{.GoVarName}} := {{.GoVarName}}HStr.String()
        ole.DeleteHString({{.GoVarName}}HStr)
    {{ end -}}
{{ end -}}


return {{range .InParams}}{{if .IsOut}}{{.GoVarName}}, {{end}}{{end -}}
    {{range .ReturnParams }}{{.GoVarName}},{{end}} nil
{{- /* remove trailing white space*/ -}}
