diff --git a/cmd/genbindings/clang2il.go b/cmd/genbindings/clang2il.go index f92e6ed0..a9c186e7 100644 --- a/cmd/genbindings/clang2il.go +++ b/cmd/genbindings/clang2il.go @@ -298,6 +298,10 @@ func parseMethod(node map[string]interface{}, mm *CppMethod) error { } } + if storageClass, ok := node["storageClass"].(string); ok && storageClass == "static" { + mm.IsStatic = true + } + if methodInner, ok := node["inner"].([]interface{}); ok { paramCounter := 0 for _, methodObj := range methodInner { diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index af0ef47c..c2df0a9a 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -69,7 +69,7 @@ func emitReturnTypeCabi(p CppParameter) string { func emitParametersCabi(m CppMethod, selfType string) string { tmp := make([]string, 0, len(m.Parameters)+1) - if selfType != "" { + if !m.IsStatic && selfType != "" { tmp = append(tmp, selfType+" self") } @@ -472,16 +472,21 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) { nativeMethodName = m.OverrideMethodName } + callTarget := "self->" + if m.IsStatic { + callTarget = c.ClassName + "::" + } + ret.WriteString(fmt.Sprintf( "%s %s_%s(%s) {\n"+ "%s"+ - "\t%sself->%s(%s);\n"+ + "\t%s%s%s(%s);\n"+ "%s"+ "}\n"+ "\n", emitReturnTypeCabi(m.ReturnType), c.ClassName, m.SafeMethodName(), emitParametersCabi(m, c.ClassName+"*"), preamble, - shouldReturn, nativeMethodName, forwarding, + shouldReturn, callTarget, nativeMethodName, forwarding, afterCall, )) } diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index e206ba35..e30abc1b 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -109,15 +109,15 @@ func (p CppParameter) parameterTypeCgo() string { func emitParametersGo(params []CppParameter) string { tmp := make([]string, 0, len(params)) - isArgcArgv := false + skipNext := false for i, p := range params { if i == 0 && IsArgcArgv(params) { - isArgcArgv = true + skipNext = true tmp = append(tmp, "args []string") - } else if i == 1 && isArgcArgv { + } else if skipNext { // Skip this parameter, already handled } else { @@ -132,14 +132,16 @@ func emitParametersGo(params []CppParameter) string { func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding string) { tmp := make([]string, 0, len(m.Parameters)+2) - tmp = append(tmp, "this.h") + if !m.IsStatic { + tmp = append(tmp, "this.h") + } - isArgcArgv := false + skipNext := false for i, p := range m.Parameters { if i == 0 && IsArgcArgv(m.Parameters) { - isArgcArgv = true + skipNext = true // QApplication constructor. Convert 'args' into Qt's wanted types // Qt has a warning in the docs saying these pointers must be valid // for the entire lifetype of QApplication, so, malloc + never free @@ -154,8 +156,9 @@ func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding st tmp = append(tmp, "argc, argv") - } else if i == 1 && isArgcArgv { + } else if skipNext { // Skip this parameter, already handled + skipNext = false } else if p.ParameterType == "QString" { // Go: convert string -> char* and len @@ -359,8 +362,13 @@ import "C" } + receiverAndMethod := `(this *` + c.ClassName + `) ` + m.SafeMethodName() + if m.IsStatic { + receiverAndMethod = c.ClassName + `_` + m.SafeMethodName() + } + ret.WriteString(` - func (this *` + c.ClassName + `) ` + m.SafeMethodName() + `(` + emitParametersGo(m.Parameters) + `) ` + returnTypeDecl + ` { + func ` + receiverAndMethod + `(` + emitParametersGo(m.Parameters) + `) ` + returnTypeDecl + ` { ` + preamble + shouldReturn + ` C.` + c.ClassName + `_` + m.SafeMethodName() + `(` + forwarding + `) ` + afterword + `} diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index 53dcb8c4..6cde9a48 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -65,6 +65,7 @@ type CppMethod struct { OverrideMethodName string // Present only if we changed the target ReturnType CppParameter // Name not used Parameters []CppParameter + IsStatic bool } func IsArgcArgv(params []CppParameter) bool {