From 0e8b48d1b825c2ad4672f68465142d8ada0fd362 Mon Sep 17 00:00:00 2001 From: mappu Date: Sat, 24 Aug 2024 11:45:36 +1200 Subject: [PATCH] genbindings: more work on integer types --- cmd/genbindings/emitcabi.go | 11 +++++++---- cmd/genbindings/emitgo.go | 19 +++++++++++++++++-- cmd/genbindings/intermediate.go | 3 ++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index 607db5f..af6e64d 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -37,7 +37,9 @@ func (p CppParameter) RenderTypeCabi() string { ret = "size_t" case "qreal": ret = "double" - case "qintptr", "quintptr": + case "qintptr": + ret = "intptr_t" + case "quintptr": ret = "uintptr_t" case "QRgb": ret = "unsigned int" @@ -155,7 +157,8 @@ func emitParametersCabi(m CppMethod, selfType string) string { // CABI: memory is moved into C.malloc/C.free // Go: converted to native Go string if m.ReturnType.ParameterType == "QString" { - tmp = append(tmp, "char** _out, size_t* _out_Strlen") + // Normally we would use size_t for a strlen, but Go calls C.GoStringN which takes a C.int + tmp = append(tmp, "char** _out, int* _out_Strlen") } else if t, ok := m.ReturnType.QListOf(); ok { // +1 pointer indirection since it's a heap array @@ -166,7 +169,7 @@ func emitParametersCabi(m CppMethod, selfType string) string { if t.ParameterType == "QString" { // Combo - tmp = append(tmp, "char*** _out, int64_t** _out_Lengths, size_t* _out_len") + tmp = append(tmp, "char*** _out, int** _out_Lengths, size_t* _out_len") // Each length is a C.int for C.GoStringN use } else if t.QtClassType() && !t.Pointer { // QList QByteArray::Split() // We need to pointer-ify each of the interior elements too @@ -490,7 +493,7 @@ extern "C" { shouldReturn = m.ReturnType.ParameterType + " ret = " afterCall += "\t// Convert QStringList from C++ memory to manually-managed C memory\n" afterCall += "\tchar** __out = static_cast(malloc(sizeof(char*) * ret.length()));\n" - afterCall += "\tint64_t* __out_Lengths = static_cast(malloc(sizeof(int64_t) * ret.length()));\n" + afterCall += "\tint* __out_Lengths = static_cast(malloc(sizeof(int) * ret.length()));\n" afterCall += "\tfor (size_t i = 0, e = ret.length(); i < e; ++i) {\n" afterCall += "\t\t// Convert QString from UTF-16 in C++ RAII memory to UTF-8 in manually-managed C memory\n" afterCall += "\t\tQByteArray b = ret[i].toUtf8();\n" diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index 14094be..8b8a51c 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -83,13 +83,20 @@ func (p CppParameter) RenderTypeGo() string { ret += "float32" case "double", "qreal": ret += "float64" - case "qsizetype": + case "qsizetype", "size_t": if C.sizeof_size_t == 4 { ret += "uint32" } else { ret += "uint64" } case "qintptr": + var ptr *int + if unsafe.Sizeof(ptr) == 8 { + ret += "int64" + } else { + ret += "int32" + } + case "quintptr": var ptr *int if unsafe.Sizeof(ptr) == 8 { ret += "uint64" @@ -113,6 +120,7 @@ func (p CppParameter) parameterTypeCgo() string { if strings.HasPrefix(tmp, "unsigned ") { tmp = "u" + tmp[9:] // Cgo uses uchar, uint instead of full name } + tmp = strings.Replace(tmp, `long long`, `longlong`, -1) return "C." + strings.Replace(tmp, " ", "_", -1) } @@ -222,6 +230,8 @@ func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding st // We want our functions to accept the Go wrapper type, and forward as cPointer() tmp = append(tmp, p.ParameterName+".cPointer()") + } else if p.IntType() || p.ParameterType == "bool" { + tmp = append(tmp, "("+p.parameterTypeCgo()+")("+p.ParameterName+")") } else { // Default tmp = append(tmp, p.ParameterName) @@ -331,7 +341,7 @@ import "C" returnTypeDecl = "string" preamble += "var _out *C.char = nil\n" - preamble += "var _out_Strlen C.size_t = 0\n" + preamble += "var _out_Strlen C.int = 0\n" // I think size_t is "better" but GoStringN() requires C.int afterword += "ret := C.GoStringN(_out, _out_Strlen)\n" afterword += "C.free(_out)\n" afterword += "return ret" @@ -370,6 +380,11 @@ import "C" afterword += "return ret1" } + } else if m.ReturnType.IntType() || m.ReturnType.ParameterType == "bool" { + // Need to cast Cgo type to Go int type + shouldReturn = "ret := " + afterword += "return (" + m.ReturnType.RenderTypeGo() + ")(ret)\n" + } receiverAndMethod := `(this *` + c.ClassName + `) ` + m.SafeMethodName() diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index 2515e46..2f0e042 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -53,7 +53,8 @@ func (p CppParameter) IntType() bool { "long", "unsigned long", "ulong", "qint32", "quint32", "longlong", "ulonglong", "qlonglong", "qulonglong", "qint64", "quint64", "int64_t", "uint64_t", "long long", "unsigned long long", "QRgb", // unsigned int - "qintptr", + "qintptr", "quintptr", + "qsizetype", "size_t", "double", "float", "qreal": return true default: