libmiqt: move binding helpers to standalone package, support const_char

This commit is contained in:
mappu 2024-10-16 18:05:07 +13:00
parent 6a01cc2d86
commit 562590fa96
6 changed files with 23 additions and 16 deletions

View File

@ -480,6 +480,7 @@ func emitBindingHeader(src *CppParsedHeader, filename string) (string, error) {
includeGuard := "GEN_" + strings.ToUpper(strings.Replace(filename, `.`, `_`, -1)) includeGuard := "GEN_" + strings.ToUpper(strings.Replace(filename, `.`, `_`, -1))
bindingInclude := "../libmiqt/libmiqt.h"
ret.WriteString(`#ifndef ` + includeGuard + ` ret.WriteString(`#ifndef ` + includeGuard + `
#define ` + includeGuard + ` #define ` + includeGuard + `
@ -489,7 +490,7 @@ func emitBindingHeader(src *CppParsedHeader, filename string) (string, error) {
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include "binding.h" #include "` + bindingInclude + `"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -134,7 +134,8 @@ func (p CppParameter) parameterTypeCgo() string {
} }
tmp := strings.Replace(p.RenderTypeCabi(), `*`, "", -1) tmp := strings.Replace(p.RenderTypeCabi(), `*`, "", -1)
if strings.HasPrefix(tmp, "const ") {
if strings.HasPrefix(tmp, "const ") && tmp != "const char" { // Special typedef to make this work for const char* signal parameters
tmp = tmp[6:] // Constness doesn't survive the CABI boundary tmp = tmp[6:] // Constness doesn't survive the CABI boundary
} }
if strings.HasPrefix(tmp, "unsigned ") { if strings.HasPrefix(tmp, "unsigned ") {
@ -234,7 +235,8 @@ func (gfs *goFileState) emitParameterGo2CABIForwarding(p CppParameter) (preamble
// Go: convert string -> miqt_string* // Go: convert string -> miqt_string*
// CABI: convert miqt_string* -> real QString // CABI: convert miqt_string* -> real QString
preamble += nameprefix + "_ms := miqt_strdupg(" + p.ParameterName + ")\n" gfs.imports["libmiqt"] = struct{}{}
preamble += nameprefix + "_ms := libmiqt.Strdupg(" + p.ParameterName + ")\n"
preamble += "defer C.free(" + nameprefix + "_ms)\n" preamble += "defer C.free(" + nameprefix + "_ms)\n"
rvalue = "(*C.struct_miqt_string)(" + nameprefix + "_ms)" rvalue = "(*C.struct_miqt_string)(" + nameprefix + "_ms)"
@ -660,14 +662,17 @@ import "C"
if len(gfs.imports) > 0 { if len(gfs.imports) > 0 {
allImports := make([]string, 0, len(gfs.imports)) allImports := make([]string, 0, len(gfs.imports))
for k, _ := range gfs.imports { for k, _ := range gfs.imports {
allImports = append(allImports, `"`+k+`"`) if k == "libmiqt" {
allImports = append(allImports, `"`+BaseModule+`/libmiqt"`)
} else {
allImports = append(allImports, `"`+k+`"`)
}
} }
sort.Strings(allImports) sort.Strings(allImports)
goSrc = strings.Replace(goSrc, `%%_IMPORTLIBS_%%`, "import (\n\t"+strings.Join(allImports, "\n\t")+"\n)", 1) goSrc = strings.Replace(goSrc, `%%_IMPORTLIBS_%%`, "import (\n\t"+strings.Join(allImports, "\n\t")+"\n)", 1)
} else { } else {
goSrc = strings.Replace(goSrc, `%%_IMPORTLIBS_%%`, "", 1) goSrc = strings.Replace(goSrc, `%%_IMPORTLIBS_%%`, "", 1)
} }
// Run gofmt over the result // Run gofmt over the result

View File

@ -15,6 +15,7 @@ import (
const ( const (
ClangSubprocessCount = 3 ClangSubprocessCount = 3
BaseModule = "github.com/mappu/miqt"
) )
func cacheFilePath(inputHeader string) string { func cacheFilePath(inputHeader string) string {

View File

@ -1,7 +1,4 @@
#include <string.h> #include "libmiqt.h"
#include <stdlib.h>
#include "binding.h"
struct miqt_string* miqt_strdup(const char* src, size_t len) { struct miqt_string* miqt_strdup(const char* src, size_t len) {
struct miqt_string* ret = (struct miqt_string*)( malloc(len + sizeof(size_t)) ); struct miqt_string* ret = (struct miqt_string*)( malloc(len + sizeof(size_t)) );

View File

@ -1,6 +1,9 @@
#ifndef MIQT_BINDING_H #ifndef MIQT_BINDING_H
#define MIQT_BINDING_H #define MIQT_BINDING_H
#include <string.h>
#include <stdlib.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -15,10 +18,10 @@ struct miqt_array {
void* data; // Separate, second allocation void* data; // Separate, second allocation
}; };
// miqt_strdup allocates a miqt_string and copies C data into it.
// The function is defined in C++.
struct miqt_string* miqt_strdup(const char* src, size_t len); struct miqt_string* miqt_strdup(const char* src, size_t len);
typedef const char const_char;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,10 +1,10 @@
package qt package libmiqt
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
/* /*
#include "binding.h" #include "libmiqt.h"
struct miqt_string* miqt_strdupg(_GoString_ gs) { struct miqt_string* miqt_strdupg(_GoString_ gs) {
return miqt_strdup(_GoStringPtr(gs), _GoStringLen(gs)); return miqt_strdup(_GoStringPtr(gs), _GoStringLen(gs));
@ -17,9 +17,9 @@ import (
"unsafe" "unsafe"
) )
// miqt_strdupg will strdup a Go string into a miqt_string*. // Strdupg will strdup a Go string into a miqt_string*.
// It is typed as returning an unsafe.Pointer because Cgo types cannot be shared // It is typed as returning an unsafe.Pointer because Cgo types cannot be shared
// across Go file boundaries. // across Go file boundaries.
func miqt_strdupg(s string) unsafe.Pointer { func Strdupg(s string) unsafe.Pointer {
return unsafe.Pointer(C.miqt_strdupg(s)) return unsafe.Pointer(C.miqt_strdupg(s))
} }