mirror of
https://github.com/mappu/miqt.git
synced 2024-12-22 00:48:38 +00:00
genbindings: implement miqt_array parameter passing
This commit is contained in:
parent
82f8063df5
commit
04399db98d
@ -78,15 +78,14 @@ func emitReturnTypeCabi(p CppParameter) string {
|
||||
return "struct miqt_string*"
|
||||
|
||||
} else if _, ok := p.QListOf(); ok {
|
||||
return "void" // Will be handled separately
|
||||
return "struct miqt_array*"
|
||||
|
||||
} else if (p.Pointer || p.ByRef) && p.QtClassType() {
|
||||
return cabiClassName(p.ParameterType) + "*" // CABI type
|
||||
return cabiClassName(p.ParameterType) + "*"
|
||||
|
||||
} else if p.QtClassType() && !p.Pointer {
|
||||
// Even if C++ returns by value, CABI is returning a heap copy (new'd, not malloc'd)
|
||||
return cabiClassName(p.ParameterType) + "*" // CABI type
|
||||
// return "void" // Handled separately with an _out pointer
|
||||
return cabiClassName(p.ParameterType) + "*"
|
||||
|
||||
} else {
|
||||
return p.RenderTypeCabi()
|
||||
@ -145,22 +144,7 @@ func emitParametersCabi(m CppMethod, selfType string) string {
|
||||
tmp = append(tmp, "struct miqt_string* "+p.ParameterName)
|
||||
|
||||
} else if t, ok := p.QListOf(); ok {
|
||||
|
||||
if t.ParameterType == "QString" {
|
||||
// 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
|
||||
tmp = append(tmp, t.RenderTypeCabi()+"* "+p.ParameterName+", size_t "+p.ParameterName+"_len")
|
||||
}
|
||||
tmp = append(tmp, "struct miqt_array* /* of "+t.RenderTypeCabi()+" */ "+p.ParameterName)
|
||||
|
||||
} else if p.QtClassType() {
|
||||
if p.ByRef || p.Pointer {
|
||||
@ -181,31 +165,6 @@ func emitParametersCabi(m CppMethod, selfType string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// If the return type is QString, we need to handle returns via extra CABI
|
||||
// parameters
|
||||
// Qt C++: memory is in QString RAII
|
||||
// CABI: memory is moved into C.malloc/C.free
|
||||
// Go: converted to native Go string
|
||||
if t, ok := m.ReturnType.QListOf(); ok {
|
||||
// +1 pointer indirection since it's a heap array
|
||||
// +1 pointer indirection for mutating remote parameter
|
||||
// = 3 for char*, 2 for most types
|
||||
|
||||
// Maybe: +1 pointer indirection if we have to lift stack types to the heap
|
||||
|
||||
if t.ParameterType == "QString" {
|
||||
// Combo
|
||||
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> QByteArray::Split()
|
||||
// We need to pointer-ify each of the interior elements too
|
||||
tmp = append(tmp, t.RenderTypeCabi()+"*** _out, size_t* _out_len")
|
||||
} else {
|
||||
tmp = append(tmp, t.RenderTypeCabi()+"** _out, size_t* _out_len")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
@ -223,11 +182,14 @@ func emitParametersCABI2CppForwarding(params []CppParameter) (preamble string, f
|
||||
|
||||
if listType.ParameterType == "QString" {
|
||||
|
||||
// miqt_array<miqt_string*>
|
||||
|
||||
// Combo (3 parameters)
|
||||
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(QString::fromUtf8(" + p.ParameterName + "[i], " + p.ParameterName + "_Lengths[i]));\n"
|
||||
preamble += "\t" + p.ParameterName + "_QList.reserve(" + p.ParameterName + "->len);\n"
|
||||
preamble += "\tmiqt_string** " + p.ParameterName + "_arr = static_cast<miqt_string**>(" + p.ParameterName + "->data);\n"
|
||||
preamble += "\tfor(size_t i = 0; i < " + p.ParameterName + "->len; ++i) {\n"
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(QString::fromUtf8(& " + p.ParameterName + "_arr[i]->data, " + p.ParameterName + "_arr[i]->len));\n"
|
||||
preamble += "\t}\n"
|
||||
tmp = append(tmp, p.ParameterName+"_QList")
|
||||
|
||||
@ -236,14 +198,19 @@ func emitParametersCABI2CppForwarding(params []CppParameter) (preamble string, f
|
||||
// The CABI has accepted two parameters - need to convert to one real QList<>
|
||||
// Create it on the stack
|
||||
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" + p.ParameterName + "_QList.reserve(" + p.ParameterName + "->len);\n"
|
||||
if listType.QtClassType() && !listType.Pointer {
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(*(" + p.ParameterName + "[i]));\n"
|
||||
preamble += "\t" + listType.PointerTo().RenderTypeCabi() + "* " + p.ParameterName + "_arr = static_cast<" + listType.PointerTo().RenderTypeCabi() + "*>(" + p.ParameterName + "->data);\n"
|
||||
preamble += "\tfor(size_t i = 0; i < " + p.ParameterName + "->len; ++i) {\n"
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(*(" + p.ParameterName + "_arr[i]));\n"
|
||||
} else if listType.IsFlagType() {
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(static_cast<" + listType.RenderTypeQtCpp() + ">(" + p.ParameterName + "[i]));\n"
|
||||
preamble += "\t" + listType.RenderTypeCabi() + "* " + p.ParameterName + "_arr = static_cast<" + listType.RenderTypeCabi() + "*>(" + p.ParameterName + "->data);\n"
|
||||
preamble += "\tfor(size_t i = 0; i < " + p.ParameterName + "->len; ++i) {\n"
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(static_cast<" + listType.RenderTypeQtCpp() + ">(" + p.ParameterName + "_arr[i]));\n"
|
||||
} else {
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(" + p.ParameterName + "[i]);\n"
|
||||
preamble += "\t" + listType.RenderTypeCabi() + "* " + p.ParameterName + "_arr = static_cast<" + listType.RenderTypeCabi() + "*>(" + p.ParameterName + "->data);\n"
|
||||
preamble += "\tfor(size_t i = 0; i < " + p.ParameterName + "->len; ++i) {\n"
|
||||
preamble += "\t\t" + p.ParameterName + "_QList.push_back(" + p.ParameterName + "_arr[i]);\n"
|
||||
}
|
||||
preamble += "\t}\n"
|
||||
tmp = append(tmp, p.ParameterName+"_QList")
|
||||
@ -351,48 +318,55 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
||||
// Combo
|
||||
// "char** _out, int64_t* _out_Lengths, size_t* _out_len")
|
||||
|
||||
shouldReturn = p.RenderTypeQtCpp() + " ret = "
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
|
||||
afterCall += indent + "// Convert QStringList from C++ memory to manually-managed C memory\n"
|
||||
afterCall += indent + "char** __out = static_cast<char**>(malloc(sizeof(char*) * ret.length()));\n"
|
||||
afterCall += indent + "int* __out_Lengths = static_cast<int*>(malloc(sizeof(int) * ret.length()));\n"
|
||||
afterCall += indent + "for (size_t i = 0, e = ret.length(); i < e; ++i) {\n"
|
||||
afterCall += indent + "\t// Convert QString from UTF-16 in C++ RAII memory to UTF-8 in manually-managed C memory\n"
|
||||
afterCall += indent + "\tQByteArray b = ret[i].toUtf8();\n"
|
||||
afterCall += indent + "\t__out[i] = static_cast<char*>(malloc(b.length()));\n"
|
||||
afterCall += indent + "\tmemcpy(__out[i], b.data(), b.length());\n"
|
||||
afterCall += indent + "\t__out_Lengths[i] = b.length();\n"
|
||||
afterCall += indent + "struct miqt_string** " + namePrefix + "_arr = static_cast<struct miqt_string**>(malloc(sizeof(struct miqt_string*) * " + namePrefix + "_ret.length()));\n"
|
||||
afterCall += indent + "for (size_t i = 0, e = " + namePrefix + "_ret.length(); i < e; ++i) {\n"
|
||||
afterCall += emitAssignCppToCabi(indent+"\t"+namePrefix+"_arr[i] = ", t, namePrefix+"_ret[i]")
|
||||
afterCall += indent + "}\n"
|
||||
afterCall += indent + "*_out = __out;\n"
|
||||
afterCall += indent + "*_out_Lengths = __out_Lengths;\n"
|
||||
afterCall += indent + "*_out_len = ret.length();\n"
|
||||
|
||||
afterCall += indent + "struct miqt_array* " + namePrefix + "_out = static_cast<struct miqt_array*>(malloc(sizeof(struct miqt_array)));\n"
|
||||
afterCall += indent + namePrefix + "_out->len = " + namePrefix + "_ret.length();\n"
|
||||
afterCall += indent + namePrefix + "_out->data = static_cast<void*>(" + namePrefix + "_arr);\n"
|
||||
|
||||
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
||||
|
||||
} else if !t.QtClassType() || (t.QtClassType() && t.Pointer) { // QList<int>, QList<QFoo*>
|
||||
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
|
||||
afterCall += indent + "// Convert QList<> from C++ memory to manually-managed C memory\n"
|
||||
afterCall += indent + "" + t.RenderTypeCabi() + "* __out = static_cast<" + t.RenderTypeCabi() + "*>(malloc(sizeof(" + t.RenderTypeCabi() + ") * " + namePrefix + "_ret.length()));\n"
|
||||
afterCall += indent + "" + t.RenderTypeCabi() + "* " + namePrefix + "_arr = static_cast<" + t.RenderTypeCabi() + "*>(malloc(sizeof(" + t.RenderTypeCabi() + ") * " + namePrefix + "_ret.length()));\n"
|
||||
afterCall += indent + "for (size_t i = 0, e = " + namePrefix + "_ret.length(); i < e; ++i) {\n"
|
||||
if t.Const {
|
||||
nonConst := t // copy
|
||||
nonConst.Const = false
|
||||
afterCall += indent + "\t__out[i] = const_cast<" + t.RenderTypeCabi() + ">(" + namePrefix + "_ret[i]);\n"
|
||||
afterCall += indent + "\t" + namePrefix + "_arr[i] = const_cast<" + t.ConstCast(false).RenderTypeCabi() + ">(" + namePrefix + "_ret[i]);\n"
|
||||
} else {
|
||||
afterCall += indent + "\t__out[i] = " + namePrefix + "_ret[i];\n"
|
||||
afterCall += indent + "\t" + namePrefix + "_arr[i] = " + namePrefix + "_ret[i];\n"
|
||||
}
|
||||
afterCall += indent + "}\n"
|
||||
afterCall += indent + "*_out = __out;\n"
|
||||
afterCall += indent + "*_out_len = " + namePrefix + "_ret.length();\n"
|
||||
|
||||
afterCall += indent + "struct miqt_array* " + namePrefix + "_out = static_cast<struct miqt_array*>(malloc(sizeof(struct miqt_array)));\n"
|
||||
afterCall += indent + "" + namePrefix + "_out->len = " + namePrefix + "_ret.length();\n"
|
||||
afterCall += indent + "" + namePrefix + "_out->data = static_cast<void*>(" + namePrefix + "_arr);\n"
|
||||
|
||||
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
||||
|
||||
} else { // QList<QFoo>
|
||||
|
||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||
|
||||
afterCall += indent + "// Convert QList<> from C++ memory to manually-managed C memory of copy-constructed pointers\n"
|
||||
afterCall += indent + "" + t.RenderTypeCabi() + "** __out = static_cast<" + t.RenderTypeCabi() + "**>(malloc(sizeof(" + t.RenderTypeCabi() + "**) * " + namePrefix + "_ret.length()));\n"
|
||||
afterCall += indent + "" + t.RenderTypeCabi() + "** " + namePrefix + "_arr = static_cast<" + t.RenderTypeCabi() + "**>(malloc(sizeof(" + t.RenderTypeCabi() + "**) * " + namePrefix + "_ret.length()));\n"
|
||||
afterCall += indent + "for (size_t i = 0, e = " + namePrefix + "_ret.length(); i < e; ++i) {\n"
|
||||
afterCall += indent + "\t__out[i] = new " + t.ParameterType + "(" + namePrefix + "_ret[i]);\n"
|
||||
afterCall += indent + "\t" + namePrefix + "_arr[i] = new " + t.ParameterType + "(" + namePrefix + "_ret[i]);\n"
|
||||
afterCall += indent + "}\n"
|
||||
afterCall += indent + "*_out = __out;\n"
|
||||
afterCall += indent + "*_out_len = " + namePrefix + "_ret.length();\n"
|
||||
|
||||
afterCall += indent + "struct miqt_array* " + namePrefix + "_out = static_cast<struct miqt_array*>(malloc(sizeof(struct miqt_array)));\n"
|
||||
afterCall += indent + "" + namePrefix + "_out->len = " + namePrefix + "_ret.length();\n"
|
||||
afterCall += indent + "" + namePrefix + "_out->data = static_cast<void*>(" + namePrefix + "_arr);\n"
|
||||
|
||||
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
||||
|
||||
}
|
||||
|
||||
@ -414,7 +388,7 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
||||
} else if p.QtClassType() && !p.Pointer {
|
||||
shouldReturn = p.ParameterType + " " + namePrefix + "_ret = "
|
||||
afterCall = indent + "// Copy-construct value returned type into heap-allocated copy\n"
|
||||
afterCall += indent + "return static_cast<" + p.ParameterType + "*>(new " + p.ParameterType + "(" + namePrefix + "_ret));\n"
|
||||
afterCall += indent + "" + assignExpression + "static_cast<" + p.ParameterType + "*>(new " + p.ParameterType + "(" + namePrefix + "_ret));\n"
|
||||
|
||||
} else if p.Const {
|
||||
shouldReturn += "(" + emitReturnTypeCabi(p) + ") "
|
||||
|
@ -187,7 +187,7 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
|
||||
|
||||
preamble += p.ParameterName + "_ms := miqt_strdupg(" + p.ParameterName + ")\n"
|
||||
preamble += "defer C.free(" + p.ParameterName + "_ms)\n"
|
||||
tmp = append(tmp, p.ParameterName+"_ms")
|
||||
tmp = append(tmp, "(*C.struct_miqt_string)("+p.ParameterName+"_ms)")
|
||||
|
||||
} else if listType, ok := p.QListOf(); ok {
|
||||
// QList<T>
|
||||
@ -200,17 +200,18 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
|
||||
|
||||
preamble += "// For the C ABI, malloc two C arrays; raw char* pointers and their lengths\n"
|
||||
preamble += p.ParameterName + "_CArray := (*[0xffff]*" + listType.parameterTypeCgo() + ")(C.malloc(C.size_t(8 * len(" + p.ParameterName + "))))\n"
|
||||
preamble += p.ParameterName + "_Lengths := (*[0xffff]C.uint64_t)(C.malloc(C.size_t(8 * len(" + p.ParameterName + "))))\n"
|
||||
preamble += "defer C.free(unsafe.Pointer(" + p.ParameterName + "_CArray))\n"
|
||||
preamble += "defer C.free(unsafe.Pointer(" + p.ParameterName + "_Lengths))\n"
|
||||
|
||||
preamble += "for i := range " + p.ParameterName + "{\n"
|
||||
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.uint64_t)(len(" + p.ParameterName + "[i]))\n"
|
||||
preamble += "single_ms := miqt_strdupg(" + p.ParameterName + "[i])\n"
|
||||
preamble += "defer C.free(unsafe.Pointer(single_ms))\n"
|
||||
preamble += p.ParameterName + "_CArray[i] = single_ms\n"
|
||||
preamble += "}\n"
|
||||
|
||||
tmp = append(tmp, "&"+p.ParameterName+"_CArray[0], &"+p.ParameterName+"_Lengths[0], C.size_t(len("+p.ParameterName+"))")
|
||||
preamble += p.ParameterName + "_ma := &C.struct_miqt_array{len: C.size_t(len(" + p.ParameterName + ")), data: unsafe.Pointer(" + p.ParameterName + "_CArray)}\n"
|
||||
preamble += "defer runtime.KeepAlive(unsafe.Pointer(" + p.ParameterName + "_ma))\n"
|
||||
|
||||
tmp = append(tmp, p.ParameterName)
|
||||
|
||||
} else {
|
||||
|
||||
@ -221,6 +222,7 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
|
||||
preamble += p.ParameterName + "_CArray := (*[0xffff]" + listType.parameterTypeCgo() + ")(C.malloc(C.size_t(8 * len(" + p.ParameterName + "))))\n"
|
||||
}
|
||||
preamble += "defer C.free(unsafe.Pointer(" + p.ParameterName + "_CArray))\n"
|
||||
|
||||
preamble += "for i := range " + p.ParameterName + "{\n"
|
||||
if listType.QtClassType() {
|
||||
preamble += p.ParameterName + "_CArray[i] = " + p.ParameterName + "[i].cPointer()\n"
|
||||
@ -229,7 +231,10 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
|
||||
}
|
||||
preamble += "}\n"
|
||||
|
||||
tmp = append(tmp, "&"+p.ParameterName+"_CArray[0], C.size_t(len("+p.ParameterName+"))")
|
||||
preamble += p.ParameterName + "_ma := &C.struct_miqt_array{len: C.size_t(len(" + p.ParameterName + ")), data: unsafe.Pointer(" + p.ParameterName + "_CArray)}\n"
|
||||
preamble += "defer runtime.KeepAlive(unsafe.Pointer(" + p.ParameterName + "_ma))\n"
|
||||
|
||||
tmp = append(tmp, p.ParameterName)
|
||||
}
|
||||
|
||||
} else if p.Pointer && p.ParameterType == "char" {
|
||||
@ -258,16 +263,6 @@ func (gfs *goFileState) emitParametersGo2CABIForwarding(m CppMethod) (preamble s
|
||||
}
|
||||
}
|
||||
|
||||
if t, ok := m.ReturnType.QListOf(); ok {
|
||||
|
||||
if t.ParameterType == "QString" {
|
||||
// Combo
|
||||
tmp = append(tmp, "&_out, &_out_Lengths, &_out_len")
|
||||
} else {
|
||||
tmp = append(tmp, "&_out, &_out_len")
|
||||
}
|
||||
}
|
||||
|
||||
return preamble, strings.Join(tmp, ", ")
|
||||
}
|
||||
|
||||
@ -425,38 +420,30 @@ import "C"
|
||||
|
||||
} else if t, ok := m.ReturnType.QListOf(); ok {
|
||||
gfs.imports["unsafe"] = struct{}{}
|
||||
shouldReturn = ""
|
||||
returnTypeDecl = "[]" + t.RenderTypeGo()
|
||||
|
||||
shouldReturn = "var ret_ma *C.struct_miqt_array = "
|
||||
if t.ParameterType == "QString" {
|
||||
// Combo
|
||||
|
||||
preamble += "var _out **C.char = nil\n"
|
||||
preamble += "var _out_Lengths *C.int = nil\n"
|
||||
preamble += "var _out_len C.size_t = 0\n"
|
||||
afterword += "ret := make([]string, int(_out_len))\n"
|
||||
afterword += "_outCast := (*[0xffff]*C.char)(unsafe.Pointer(_out)) // hey ya\n"
|
||||
afterword += "_out_LengthsCast := (*[0xffff]C.int)(unsafe.Pointer(_out_Lengths))\n"
|
||||
afterword += "for i := 0; i < int(_out_len); i++ {\n"
|
||||
afterword += "ret[i] = C.GoStringN(_outCast[i], _out_LengthsCast[i])\n"
|
||||
afterword += "ret := make([]string, int(ret_ma.len))\n"
|
||||
afterword += "_outCast := (*[0xffff]*C.struct_miqt_string)(unsafe.Pointer(ret_ma.data)) // hey ya\n"
|
||||
afterword += "for i := 0; i < int(ret_ma.len); i++ {\n"
|
||||
afterword += "ret[i] = C.GoStringN(&_outCast[i].data, C.int(int64(_outCast[i].len)))\n"
|
||||
afterword += "C.free(unsafe.Pointer(_outCast[i])) // free the inner miqt_string*\n"
|
||||
afterword += "}\n"
|
||||
afterword += "C.free(unsafe.Pointer(_out))\n"
|
||||
afterword += "C.free(unsafe.Pointer(ret_ma))\n"
|
||||
afterword += "return ret\n"
|
||||
|
||||
} else {
|
||||
|
||||
afterword += "ret := make([]" + t.RenderTypeGo() + ", int(ret_ma.len))\n"
|
||||
if t.QtClassType() {
|
||||
preamble += "var _out **" + t.parameterTypeCgo() + " = nil\n"
|
||||
afterword += "_outCast := (*[0xffff]*" + t.parameterTypeCgo() + ")(unsafe.Pointer(ret_ma.data)) // so fresh so clean\n"
|
||||
} else {
|
||||
preamble += "var _out *" + t.parameterTypeCgo() + " = nil\n"
|
||||
afterword += "_outCast := (*[0xffff]" + t.parameterTypeCgo() + ")(unsafe.Pointer(ret_ma.data)) // mrs jackson\n"
|
||||
}
|
||||
preamble += "var _out_len C.size_t = 0\n"
|
||||
afterword += "ret := make([]" + t.RenderTypeGo() + ", int(_out_len))\n"
|
||||
if t.QtClassType() {
|
||||
afterword += "_outCast := (*[0xffff]*" + t.parameterTypeCgo() + ")(unsafe.Pointer(_out)) // so fresh so clean\n"
|
||||
} else {
|
||||
afterword += "_outCast := (*[0xffff]" + t.parameterTypeCgo() + ")(unsafe.Pointer(_out)) // mrs jackson\n"
|
||||
}
|
||||
afterword += "for i := 0; i < int(_out_len); i++ {\n"
|
||||
afterword += "for i := 0; i < int(ret_ma.len); i++ {\n"
|
||||
if t.QtClassType() {
|
||||
if !t.Pointer {
|
||||
// new, but then dereference it
|
||||
@ -468,7 +455,7 @@ import "C"
|
||||
afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n"
|
||||
}
|
||||
afterword += "}\n"
|
||||
afterword += "C.free(unsafe.Pointer(_out))\n"
|
||||
afterword += "C.free(unsafe.Pointer(ret_ma))\n"
|
||||
afterword += "return ret\n"
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,19 @@ func (p *CppParameter) CopyWithAlias(alias CppParameter) CppParameter {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *CppParameter) PointerTo() CppParameter {
|
||||
ret := *p // Copy
|
||||
ret.Pointer = true
|
||||
ret.PointerCount++
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *CppParameter) ConstCast(isConst bool) CppParameter {
|
||||
ret := *p // Copy
|
||||
ret.Const = isConst
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *CppParameter) UnderlyingType() string {
|
||||
if p.TypeAlias != "" {
|
||||
return p.TypeAlias
|
||||
@ -120,11 +133,15 @@ func (p CppParameter) IsEnum() bool {
|
||||
|
||||
func (p CppParameter) QListOf() (CppParameter, bool) {
|
||||
if strings.HasPrefix(p.ParameterType, "QList<") && strings.HasSuffix(p.ParameterType, `>`) {
|
||||
return parseSingleTypeString(p.ParameterType[6 : len(p.ParameterType)-1]), true
|
||||
ret := parseSingleTypeString(p.ParameterType[6 : len(p.ParameterType)-1])
|
||||
ret.ParameterName = p.ParameterName + "_lv"
|
||||
return ret, true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(p.ParameterType, "QVector<") && strings.HasSuffix(p.ParameterType, `>`) {
|
||||
return parseSingleTypeString(p.ParameterType[8 : len(p.ParameterType)-1]), true
|
||||
ret := parseSingleTypeString(p.ParameterType[8 : len(p.ParameterType)-1])
|
||||
ret.ParameterName = p.ParameterName + "_vv"
|
||||
return ret, true
|
||||
}
|
||||
|
||||
return CppParameter{}, false
|
||||
|
@ -13,9 +13,13 @@ struct miqt_string* miqt_strdupg(_GoString_ gs) {
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// miqt_strdupg will strdup a Go string into a miqt_string*.
|
||||
// It is typed as returning an unsafe.Pointer because Cgo types cannot be shared
|
||||
// across Go file boundaries.
|
||||
func miqt_strdupg(s string) unsafe.Pointer {
|
||||
return C.miqt_strdupg(s)
|
||||
return unsafe.Pointer(C.miqt_strdupg(s))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user