Wie man einen BMax-String aus einer C-Funktion zurück gibt
Übersicht

![]() |
BtbNBetreff: Wie man einen BMax-String aus einer C-Funktion zurück gibt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zuerst einmal muss man die blitz.h aus brl.blitz includieren, dies geschieht so:
Code: [AUSKLAPPEN] #include <brl.mod/blitz.mod/blitz.h>
Das BMK setzt automatisch die Includepfade so, dass dies funktioniert. Nun unsere Test-Funktion: Code: [AUSKLAPPEN] BBString *myCFunction()
{ char *myCString = "Hallo, das ist ein Test."; BBString *myBMaxString = bbStringFromCString(myCString); return myBMaxString; } Hier wird zunächst eine Funktion mit dem Rückgabetyp BBString* erstellt, was den Strings von BMax entspricht und in blitz_string.h definiert ist. Die erste Zeile der Funktion sollte klar sein. In der zweiten Zeile benutze ich die Funktion bbStringFromCString, welche die Funktion ist, die sich hinter String.FromCString() in BMax verbirgt. Sie macht aus unserem CString einen BMax-String, welcher anschließend zurück gegeben wird. Und hier das zugehörige BMax-Programm zum testen: Code: [AUSKLAPPEN] SuperStrict
Framework BRL.Blitz Import "main.c" Extern "C" Function myCFunction:String() EndExtern WriteStdOut(myCFunction()+"~n") End Im grunde verlagert man hier nur den Teil, den man sonst in BMax machen würde in den C-Code. Ich finde aber, dass es dort wesentlich besser aufgehoben ist, als im BMax-Code und für mehr übersichtlichkeit sorgt. Wenn ich rausfinde, wie man Types sicher aus einer C-Funktion heraus zurück gibt, werde ichs hier schreiben. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
BBObject in blitz_object.h
bzw. BBObject *bbObjectNew in der zugehörigen .c File Grundklasse ist bbObjectClass, die müsstest du dem Super zuweisen des BBObject soferns direkt von Object abgeleitet wär. Aber es ist immer wieder interessant da rein zu gucken, hab grad festgestellt das Mark dem GC wieder einen 3ten Modus verpasst hat ... diesmal BBGC_AGGRESSIVE (-1), was der wohl macht ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Gibt es bei folgendem Test Memoryleaks?
test.c Code: [AUSKLAPPEN] #include <string.h>
#include <brl.mod/blitz.mod/blitz.h> struct TInfo { BBString *a; BBString *b; BBString *c; }; BBINT getABC(struct TInfo *info) { char *a = "eins"; char *b = "zwei"; char *c = "drei"; info->a = bbStringFromCString(a); info->b = bbStringFromCString(b); info->c = bbStringFromCString(c); return 123; } test.bmx Code: [AUSKLAPPEN] SuperStrict
Framework BRL.Blitz Import "test.c" Type TInfo Field A : String Field B : String Field C : String End Type Extern "C" Function getABC:Int(info : Byte Ptr) End Extern Global info:TInfo = New TInfo WriteStdout(getABC(info) + "~n") WriteStdout(info.A + "~n") WriteStdout(info.B + "~n") WriteStdout(info.C + "~n") Wenn ich info->a != NULL in getABC prüfe, dann kommt FALSE heraus. Schlussfolgerung ist, dass info.A bereits ein gültiger String ist (nur halt mit Länge 0). Wenn ich den jetzt mit info->a = bbStringFromCString(a); überschreibe, existiert der alte, leere String doch noch weiter im Heap-Universum? Wenn ja, wie kann ich den vorher löschen? In Bedacht auf GC wird ein free(info->a) wohl nicht reichen, oder? mfg olli |
||
vertex.dreamfall.at | GitHub |
![]() |
FOODy |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich würde es mit bbObjectRelease(BBObject* obj) versuchen. (oder direkt das BBRELEASE Makro benutzen)
Sobald es keine Referenzen gibt wird das Objekt von dem GC freigegeben. Grüße, FOODy |
||
BlitzMax + MaxGUI, 64-bit Arch Linux: Intel Core² E8500 | 8 GB Ram | GeForce GTX 460 · 1024 MB |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke!
BBString ist eine Struct, meinst du, dass es da mit bbObjectRelease geht? Wie stehts mit bbStringClass? Denke, die kann ich an bbObjectRelease übergeben, aber übergibt mir BMax an meine C-Funktion dann auch eine Referenz auf bbStringClass? |
||
vertex.dreamfall.at | GitHub |
![]() |
FOODy |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du könntest den BBString einfach zu ein BBObject casten, da die Struktur mehr oder weniger gleich ist, oder direkt das BBRELEASE Makro verwenden, welches auch von bbObjectRelease aufgerufen wird.
String in BlitzMax ist nichts weiter als ein BBString* in C. Also wird BlitzMax dir eine BBString* Instanz übergeben. bbStringClass ist eine Instanz die die Stringklasse beschreibt. (Sie beinhaltet die vtable, Kontruktor/Destruktor, ...) Grüße, FOODy |
||
BlitzMax + MaxGUI, 64-bit Arch Linux: Intel Core² E8500 | 8 GB Ram | GeForce GTX 460 · 1024 MB |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
OK, ich habe es jetzt:
Man darf nicht zu bbObject casten, und dann mit bbObjectRelease freigeben sondern muss mit if(info->a != NULL) bbStringClass.free(info->a); das ganze erledigen. Warum? Code: [AUSKLAPPEN] static void bbStringFree( BBObject *o ){
BBString *str=(BBString*)o; if( str==&bbEmptyString ){ str->refs=BBGC_MANYREFS; return; } bbGCMemFree( str,sizeof(BBString)+str->length*sizeof(BBChar) ); } das ist die free-"Methode" der bbStringClass. Sie prüft nämlich zusätzlich, ob der String == bbEmptyString ist, der nicht vom GC freigegeben werden darf. Weiß aber nicht 100% ob bbReleaseObject vllt. doch die bbStringFree Funktion indirekt aufruft?! |
||
vertex.dreamfall.at | GitHub |
porcus |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Man kann auch einfach mit byte ptr und String.FromCString(blurp) arbeiten um einen String von
nem C Teil in den Bmax Teil zu nehmen. |
||
*Account deaktiviert* |
![]() |
BtbN |
![]() Antworten mit Zitat ![]() |
---|---|---|
Was sehr memleak-anfällig ist. | ||
![]() |
FOODy |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Vertex:
Das einzige was du machen musst ist es BBRELEASE aufzurufen. Sobald eine Instanz keine Referenzen mehr hat wird die vom GC automatisch freigegeben. (Nicht unbedingt sofort) BBClass erbt von BBGCPool und definiert die free-Funktion (bzw ein Pointer der auf eine free-Funktion zeigt) die von dem GC aufgerufen wird. (also z.b. das bbStringFree oder bbObjectFree) bbGCFree "markiert" die Instanz, damit die beim nächsten GC aufruf freigegeben wird. (wird von BBRELEASE aufgerufen) Mit bbGCMemFree wird der Speichern endgültig freigegeben. (wird z.b. von bbStringFree und bbObjectFree aufgerufen, wenn die Instanz keine Null-Instanz repräsentiert) Grüße, FOODy |
||
BlitzMax + MaxGUI, 64-bit Arch Linux: Intel Core² E8500 | 8 GB Ram | GeForce GTX 460 · 1024 MB |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group