genbindings: basic support for QList<> of non qt pointer type

This commit is contained in:
mappu 2024-08-17 11:28:49 +12:00
parent 9a78d87e00
commit a579f80d34
2 changed files with 18 additions and 9 deletions

View File

@ -9,6 +9,8 @@ import (
func (p CppParameter) RenderTypeCpp() string { func (p CppParameter) RenderTypeCpp() string {
ret := p.ParameterType ret := p.ParameterType
switch p.ParameterType { switch p.ParameterType {
case "uchar":
ret = "unsigned char"
case "uint": case "uint":
ret = "unsigned int" ret = "unsigned int"
case "ulong": case "ulong":
@ -31,6 +33,8 @@ func (p CppParameter) RenderTypeCpp() string {
ret = "uint64_t" ret = "uint64_t"
case "qfloat16": case "qfloat16":
ret = "_Float16" // No idea where this typedef comes from, but it exists ret = "_Float16" // No idea where this typedef comes from, but it exists
case "qsizetype":
ret = "size_t"
case "QRgb": case "QRgb":
ret = "unsigned int" ret = "unsigned int"
} }
@ -84,8 +88,7 @@ func emitParametersCabi(m CppMethod, selfType string) string {
} 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
// TODO support QList<int> tmp = append(tmp, t.RenderTypeCpp()+"* "+p.ParameterName+", size_t "+p.ParameterName+"_len")
tmp = append(tmp, t.ParameterType+"* "+p.ParameterName+", size_t "+p.ParameterName+"_len")
} }
} else if (p.ByRef || p.Pointer) && p.QtClassType() { } else if (p.ByRef || p.Pointer) && p.QtClassType() {
@ -114,7 +117,7 @@ func emitParametersCabi(m CppMethod, selfType string) string {
tmp = append(tmp, "char** _out, size_t* _out_Strlen") tmp = append(tmp, "char** _out, size_t* _out_Strlen")
} else if t, ok := m.ReturnType.QListOf(); ok { } else if t, ok := m.ReturnType.QListOf(); ok {
tmp = append(tmp, t.ParameterType+"** _out, size_t* _out_len") tmp = append(tmp, t.RenderTypeCpp()+"** _out, size_t* _out_len")
} }

View File

@ -91,6 +91,14 @@ func (p CppParameter) RenderTypeGo() string {
return ret // ignore const return ret // ignore const
} }
func (p CppParameter) parameterTypeCgo() string {
tmp := strings.Replace(p.RenderTypeCpp(), `*`, "", -1)
if strings.HasPrefix(tmp, "unsigned ") {
tmp = "u" + tmp[9:] // Cgo uses uchar, uint instead of full name
}
return "C." + strings.Replace(tmp, " ", "_", -1)
}
func emitParametersGo(params []CppParameter) string { func emitParametersGo(params []CppParameter) string {
tmp := make([]string, 0, len(params)) tmp := make([]string, 0, len(params))
for _, p := range params { for _, p := range params {
@ -121,8 +129,8 @@ func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding st
// Combo // Combo
preamble += "// For the C ABI, malloc two C arrays; raw char* pointers and their lengths\n" preamble += "// For the C ABI, malloc two C arrays; raw char* pointers and their lengths\n"
preamble += p.ParameterName + "_CArray := (*[0xffff]*C." + listType.ParameterType + ")(C.malloc(c.ulong(8 * len(" + p.ParameterName + "))))\n" preamble += p.ParameterName + "_CArray := (*[0xffff]*" + listType.parameterTypeCgo() + ")(C.malloc(c.ulong(8 * len(" + p.ParameterName + "))))\n"
preamble += p.ParameterName + "_Lengths := (*[0xffff]*C." + listType.ParameterType + ")(C.malloc(c.ulong(8 * len(" + p.ParameterName + "))))\n" preamble += p.ParameterName + "_Lengths := (*[0xffff]*C.size_t)(C.malloc(c.ulong(8 * len(" + p.ParameterName + "))))\n"
preamble += "defer C.free(" + p.ParameterName + "_CArray)\n" preamble += "defer C.free(" + p.ParameterName + "_CArray)\n"
preamble += "defer C.free(" + p.ParameterName + "_Lengths)\n" preamble += "defer C.free(" + p.ParameterName + "_Lengths)\n"
preamble += "for i := range " + p.ParameterName + "{\n" preamble += "for i := range " + p.ParameterName + "{\n"
@ -136,10 +144,8 @@ func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding st
} else { } else {
// TODO handle QList<int>
preamble += "// For the C ABI, malloc a C array of raw pointers\n" preamble += "// For the C ABI, malloc a C array of raw pointers\n"
preamble += p.ParameterName + "_CArray := (*[0xffff]*C." + listType.ParameterType + ")(C.malloc(c.ulong(8 * len(" + p.ParameterName + "))))\n" preamble += p.ParameterName + "_CArray := (*[0xffff]*" + listType.parameterTypeCgo() + ")(C.malloc(c.ulong(8 * len(" + p.ParameterName + "))))\n"
preamble += "defer C.free(" + p.ParameterName + "_CArray)\n" preamble += "defer C.free(" + p.ParameterName + "_CArray)\n"
preamble += "for i := range " + p.ParameterName + "{\n" preamble += "for i := range " + p.ParameterName + "{\n"
preamble += p.ParameterName + "_CArray[i] = " + p.ParameterName + "[i].cPointer()\n" preamble += p.ParameterName + "_CArray[i] = " + p.ParameterName + "[i].cPointer()\n"
@ -277,7 +283,7 @@ import "C"
shouldReturn = "" shouldReturn = ""
returnTypeDecl = "[]" + t.RenderTypeGo() returnTypeDecl = "[]" + t.RenderTypeGo()
preamble += "var _out **C." + t.ParameterType + " = nil\n" preamble += "var _out **" + t.parameterTypeCgo() + " = nil\n"
preamble += "var _out_len C.size_t = 0\n" preamble += "var _out_len C.size_t = 0\n"
afterword += "ret := make([]" + t.RenderTypeGo() + ", _out_Strlen)\n" afterword += "ret := make([]" + t.RenderTypeGo() + ", _out_Strlen)\n"
afterword += "for i := 0; i < _out_len; i++ {\n" afterword += "for i := 0; i < _out_len; i++ {\n"