genbindings: assorted pointer correctness fixes

This commit is contained in:
mappu 2024-08-25 15:31:51 +12:00
parent 8fb92cfd3a
commit 0401231ab6
2 changed files with 26 additions and 8 deletions

View File

@ -128,6 +128,12 @@ func emitParametersCabi(m CppMethod, selfType string) string {
// Combo // Combo
tmp = append(tmp, "char** "+p.ParameterName+", uint64_t* "+p.ParameterName+"_Lengths, size_t "+p.ParameterName+"_len") 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 { } else {
// The Go code has called this with two arguments: T* and len // The Go code has called this with two arguments: T* and len
// Declare that we take two parameters // 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.ParameterType + " " + p.ParameterName + "_QList;\n"
preamble += "\t" + p.ParameterName + "_QList.reserve(" + p.ParameterName + "_len);\n" preamble += "\t" + p.ParameterName + "_QList.reserve(" + p.ParameterName + "_len);\n"
preamble += "\tfor(size_t i = 0; i < " + p.ParameterName + "_len; ++i) {\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" preamble += "\t}\n"
tmp = append(tmp, p.ParameterName+"_QList") tmp = append(tmp, p.ParameterName+"_QList")
} }

View File

@ -158,7 +158,7 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
preamble += "argv[i] = C.CString(args[i])\n" preamble += "argv[i] = C.CString(args[i])\n"
preamble += "}\n" preamble += "}\n"
tmp = append(tmp, "argc, argv") tmp = append(tmp, "argc, &argv[0]")
} else if skipNext { } else if skipNext {
// Skip this parameter, already handled // 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 += "single_cstring := C.CString(" + p.ParameterName + "[i])\n"
preamble += "defer C.free(unsafe.Pointer(single_cstring))\n" preamble += "defer C.free(unsafe.Pointer(single_cstring))\n"
preamble += p.ParameterName + "_CArray[i] = 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" 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 { } else {
@ -223,13 +223,14 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
preamble += "defer C.free(unsafe.Pointer(" + p.ParameterName + "_Cstring))\n" preamble += "defer C.free(unsafe.Pointer(" + p.ParameterName + "_Cstring))\n"
tmp = append(tmp, p.ParameterName+"_Cstring") 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 // The C++ type is a pointer to Qt class
// We want our functions to accept the Go wrapper type, and forward as cPointer() // We want our functions to accept the Go wrapper type, and forward as cPointer()
tmp = append(tmp, p.ParameterName+".cPointer()") tmp = append(tmp, p.ParameterName+".cPointer()")
} else if p.IntType() || p.ParameterType == "bool" { } 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 tmp = append(tmp, "(*"+p.parameterTypeCgo()+")(unsafe.Pointer("+p.ParameterName+"))") // n.b. This may not work if the integer type conversion was wrong
} else { } else {
tmp = append(tmp, "("+p.parameterTypeCgo()+")("+p.ParameterName+")") tmp = append(tmp, "("+p.parameterTypeCgo()+")("+p.ParameterName+")")
@ -359,6 +360,8 @@ import "C"
// internal pointer // internal pointer
gfs.imports["unsafe"] = struct{}{} gfs.imports["unsafe"] = struct{}{}
returnTypeDecl = "unsafe.Pointer" returnTypeDecl = "unsafe.Pointer"
shouldReturn = "ret := "
afterword += "return (unsafe.Pointer)(ret)\n"
} else if m.ReturnType.ParameterType == "QString" { } else if m.ReturnType.ParameterType == "QString" {
shouldReturn = "" shouldReturn = ""
@ -406,7 +409,12 @@ import "C"
} }
afterword += "for i := 0; i < int(_out_len); i++ {\n" afterword += "for i := 0; i < int(_out_len); i++ {\n"
if t.QtClassType() { 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 } else { // plain int type
afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n" afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n"
} }
@ -419,7 +427,7 @@ import "C"
// Construct our Go type based on this inner CABI type // Construct our Go type based on this inner CABI type
shouldReturn = "ret := " shouldReturn = "ret := "
if m.ReturnType.Pointer { if m.ReturnType.Pointer || m.ReturnType.ByRef {
gfs.imports["unsafe"] = struct{}{} gfs.imports["unsafe"] = struct{}{}
afterword = "return new" + m.ReturnType.ParameterType + "_U(unsafe.Pointer(ret))" afterword = "return new" + m.ReturnType.ParameterType + "_U(unsafe.Pointer(ret))"