From d32ab82d730f028d7d403ca3915caa01e1d8602a Mon Sep 17 00:00:00 2001 From: mappu Date: Sat, 20 May 2017 23:02:58 +1200 Subject: [PATCH] don't pass go strings to c - pass char*+len, callee must call free() --- main.go | 35 +++++++++++++++++++++-------------- qbolt.h | 14 +++++++++++--- qbolt/boltdb.cpp | 20 +++++++++++++------- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/main.go b/main.go index 706bc93..debb0a9 100644 --- a/main.go +++ b/main.go @@ -31,24 +31,27 @@ func Bolt_Options_New_Readonly() ObjectReference { } //export Bolt_Open -func Bolt_Open(path string, mode uint32, opts ObjectReference) (ObjectReference, string) { +func Bolt_Open(path string, mode uint32, opts ObjectReference) (ObjectReference, *C.char, int) { optsIFC, ok := gms.Get(opts) if !ok { - return 0, "" + errMsg := NullObjectReference.Error() + return 0, C.CString(errMsg), len(errMsg) } ptrBoltOps, ok := optsIFC.(*bolt.Options) if !ok { - return 0, "" + errMsg := NullObjectReference.Error() + return 0, C.CString(errMsg), len(errMsg) } ptrDB, err := bolt.Open(path, os.FileMode(mode), ptrBoltOps) if err != nil { - return 0, err.Error() + errMsg := err.Error() + return 0, C.CString(errMsg), len(errMsg) } dbRef := gms.Put(ptrDB) - return dbRef, "" + return dbRef, nil, 0 } func withBoltDBReference(b ObjectReference, fn func(db *bolt.DB) error) error { @@ -134,28 +137,31 @@ const ( ) //export GetNext -func GetNext(oRef ObjectReference) (int64, string) { +func GetNext(oRef ObjectReference) (int64, *C.char, int) { pNC_Iface, ok := gms.Get(oRef) if !ok { - return ERROR_AND_STOP_CALLING, NullObjectReference.Error() + msg := NullObjectReference.Error() + return ERROR_AND_STOP_CALLING, C.CString(msg), len(msg) } pNC, ok := pNC_Iface.(*NextCall) if !ok { - return ERROR_AND_STOP_CALLING, NullObjectReference.Error() + msg := NullObjectReference.Error() + return ERROR_AND_STOP_CALLING, C.CString(msg), len(msg) } cr, ok := <-pNC.content if !ok { gms.Delete(oRef) - return FINISHED_OK, "" + return FINISHED_OK, nil, 0 } if cr.e != nil { - return ERROR_AND_KEEP_CALLING, cr.e.Error() + msg := cr.e.Error() + return ERROR_AND_KEEP_CALLING, C.CString(msg), len(msg) } - return REAL_MESSAGE, cr.s + return REAL_MESSAGE, C.CString(cr.s), len(cr.s) } //export Bolt_ListBucketsAtRoot @@ -164,17 +170,18 @@ func Bolt_ListBucketsAtRoot(b ObjectReference) ObjectReference { } //export Bolt_Close -func Bolt_Close(b ObjectReference) string { +func Bolt_Close(b ObjectReference) (*C.char, int) { err := withBoltDBReference(b, func(db *bolt.DB) error { return db.Close() }) if err != nil { - return err.Error() + msg := err.Error() + return C.CString(msg), len(msg) } gms.Delete(b) - return "" + return nil, 0 } func main() { diff --git a/qbolt.h b/qbolt.h index 58564ae..83962d6 100644 --- a/qbolt.h +++ b/qbolt.h @@ -61,7 +61,8 @@ extern GoInt64 Bolt_Options_New_Readonly(); /* Return type for Bolt_Open */ struct Bolt_Open_return { GoInt64 r0; - GoString r1; + char* r1; + GoInt r2; }; extern struct Bolt_Open_return Bolt_Open(GoString p0, GoUint32 p1, GoInt64 p2); @@ -71,14 +72,21 @@ extern GoInt64 Bolt_ListBuckets(GoInt64 p0, GoSlice p1); /* Return type for GetNext */ struct GetNext_return { GoInt64 r0; - GoString r1; + char* r1; + GoInt r2; }; extern struct GetNext_return GetNext(GoInt64 p0); extern GoInt64 Bolt_ListBucketsAtRoot(GoInt64 p0); -extern GoString Bolt_Close(GoInt64 p0); +/* Return type for Bolt_Close */ +struct Bolt_Close_return { + char* r0; + GoInt r1; +}; + +extern struct Bolt_Close_return Bolt_Close(GoInt64 p0); #ifdef __cplusplus } diff --git a/qbolt/boltdb.cpp b/qbolt/boltdb.cpp index 92875ac..5f9dbaf 100644 --- a/qbolt/boltdb.cpp +++ b/qbolt/boltdb.cpp @@ -13,8 +13,9 @@ BoltDB* BoltDB::createFrom(QString filePath, QString &errorOut) GoString filePathGS = Interop::toGoString_WeakRef(&filePathBytes); auto open_ret = ::Bolt_Open(filePathGS, 0444, opts); - if (open_ret.r1.n != 0) { - errorOut = QString(open_ret.r1.p); + if (open_ret.r2 != 0) { + errorOut = QString::fromUtf8(open_ret.r1, open_ret.r2); + free(open_ret.r1); return nullptr; } @@ -38,11 +39,13 @@ bool BoltDB::listBucketsAtRoot(QString& errorOut, NameReciever cb) auto gnr = ::GetNext(listJob); if (gnr.r0 == ERROR_AND_STOP_CALLING) { - errorOut.append(QString(gnr.r1.p)); // log error + errorOut.append(QString::fromUtf8(gnr.r1, gnr.r2)); // log error + free(gnr.r1); break; // done } else if (gnr.r0 == ERROR_AND_KEEP_CALLING) { - errorOut.append(QString(gnr.r1.p)); // log error + errorOut.append(QString::fromUtf8(gnr.r1, gnr.r2)); // log error + free(gnr.r1); continue; } else if (gnr.r0 == FINISHED_OK) { @@ -50,7 +53,8 @@ bool BoltDB::listBucketsAtRoot(QString& errorOut, NameReciever cb) break; } else if (gnr.r0 == REAL_MESSAGE) { - cb(QByteArray(gnr.r1.p, gnr.r1.n)); + cb(QByteArray(gnr.r1, gnr.r2)); + free(gnr.r1); continue; } } @@ -60,9 +64,11 @@ bool BoltDB::listBucketsAtRoot(QString& errorOut, NameReciever cb) BoltDB::~BoltDB() { - GoString err = ::Bolt_Close(this->gmsDbRef); - if (err.n != 0) { + auto err = ::Bolt_Close(this->gmsDbRef); + if (err.r1 != 0) { // Error closing database! // Need to display an alert... somewhere + + free(err.r0); } }