From 0401231ab6bbfb650b333ea5fdb44400ffa0a94f Mon Sep 17 00:00:00 2001 From: mappu Date: Sun, 25 Aug 2024 15:31:51 +1200 Subject: [PATCH] genbindings: assorted pointer correctness fixes --- cmd/genbindings/emitcabi.go | 12 +++++++++++- cmd/genbindings/emitgo.go | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index 8bc17a9..4aea9d2 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -128,6 +128,12 @@ func emitParametersCabi(m CppMethod, selfType string) string { // Combo tmp = append(tmp, "char** "+p.ParameterName+", uint64_t* "+p.ParameterName+"_Lengths, size_t "+p.ParameterName+"_len") + } else if t.QtClassType() && !t.Pointer { + // The Go code can only work with Qt types as pointers, so the CABI needs to take an array of + // pointers, not an array of values + // Needs one more level of indirection + tmp = append(tmp, t.RenderTypeCabi()+"** "+p.ParameterName+", size_t "+p.ParameterName+"_len") + } else { // The Go code has called this with two arguments: T* and len // Declare that we take two parameters @@ -212,7 +218,11 @@ func emitParametersCABI2CppForwarding(params []CppParameter) (preamble string, f preamble += "\t" + p.ParameterType + " " + p.ParameterName + "_QList;\n" preamble += "\t" + p.ParameterName + "_QList.reserve(" + p.ParameterName + "_len);\n" preamble += "\tfor(size_t i = 0; i < " + p.ParameterName + "_len; ++i) {\n" - preamble += "\t\t" + p.ParameterName + "_QList.push_back(" + p.ParameterName + "[i]);\n" + if listType.QtClassType() && !listType.Pointer { + preamble += "\t\t" + p.ParameterName + "_QList.push_back(*(" + p.ParameterName + "[i]));\n" + } else { + preamble += "\t\t" + p.ParameterName + "_QList.push_back(" + p.ParameterName + "[i]);\n" + } preamble += "\t}\n" tmp = append(tmp, p.ParameterName+"_QList") } diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index 8e376c6..4d95766 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -158,7 +158,7 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s preamble += "argv[i] = C.CString(args[i])\n" preamble += "}\n" - tmp = append(tmp, "argc, argv") + tmp = append(tmp, "argc, &argv[0]") } else if skipNext { // Skip this parameter, already handled @@ -191,10 +191,10 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s preamble += "single_cstring := C.CString(" + p.ParameterName + "[i])\n" preamble += "defer C.free(unsafe.Pointer(single_cstring))\n" preamble += p.ParameterName + "_CArray[i] = single_cstring\n" - preamble += p.ParameterName + "__Lengths[i] = (C.size_t)(len(" + p.ParameterName + "[i]))\n" + preamble += p.ParameterName + "_Lengths[i] = (C.size_t)(len(" + p.ParameterName + "[i]))\n" preamble += "}\n" - tmp = append(tmp, "&"+p.ParameterName+"_CArray[0], "+p.ParameterName+"_Lengths, C.ulong(len("+p.ParameterName+"))") + tmp = append(tmp, "&"+p.ParameterName+"_CArray[0], &"+p.ParameterName+"_Lengths[0], C.ulong(len("+p.ParameterName+"))") } else { @@ -223,13 +223,14 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s preamble += "defer C.free(unsafe.Pointer(" + p.ParameterName + "_Cstring))\n" tmp = append(tmp, p.ParameterName+"_Cstring") - } else if (p.Pointer || p.ByRef) && p.QtClassType() { + } else if /*(p.Pointer || p.ByRef) &&*/ p.QtClassType() { // The C++ type is a pointer to Qt class // 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" { - if p.Pointer { + if p.Pointer || p.ByRef { + gfs.imports["unsafe"] = struct{}{} tmp = append(tmp, "(*"+p.parameterTypeCgo()+")(unsafe.Pointer("+p.ParameterName+"))") // n.b. This may not work if the integer type conversion was wrong } else { tmp = append(tmp, "("+p.parameterTypeCgo()+")("+p.ParameterName+")") @@ -359,6 +360,8 @@ import "C" // internal pointer gfs.imports["unsafe"] = struct{}{} returnTypeDecl = "unsafe.Pointer" + shouldReturn = "ret := " + afterword += "return (unsafe.Pointer)(ret)\n" } else if m.ReturnType.ParameterType == "QString" { shouldReturn = "" @@ -406,7 +409,12 @@ import "C" } afterword += "for i := 0; i < int(_out_len); i++ {\n" if t.QtClassType() { - afterword += "ret[i] = new" + t.ParameterType + "(_outCast[i])\n" + if !t.Pointer { + // new, but then dereference it + afterword += "ret[i] = *new" + t.ParameterType + "(_outCast[i])\n" + } else { + afterword += "ret[i] = new" + t.ParameterType + "(_outCast[i])\n" + } } else { // plain int type afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n" } @@ -419,7 +427,7 @@ import "C" // Construct our Go type based on this inner CABI type shouldReturn = "ret := " - if m.ReturnType.Pointer { + if m.ReturnType.Pointer || m.ReturnType.ByRef { gfs.imports["unsafe"] = struct{}{} afterword = "return new" + m.ReturnType.ParameterType + "_U(unsafe.Pointer(ret))"