Bass.dll - Pointer zu einem Objekt konvertieren
Übersicht

![]() |
ArtemisBetreff: Bass.dll - Pointer zu einem Objekt konvertieren |
![]() Antworten mit Zitat ![]() |
---|---|---|
So, ich arbeite grad daran, dass ich BlitzMax auf Plugininfos der Bass.dll zugreifen kann. Das ganze sieht so aus:
C-Code, der im Manual steht: Code: [AUSKLAPPEN] BASS_PLUGININFO *BASS_PluginGetInfo(
HPLUGIN handle ); typedef struct { DWORD version; DWORD formatc; BASS_PLUGINFORM *formats; } BASS_PLUGININFO; typedef struct { DWORD ctype; char *name; char *exts; } BASS_PLUGINFORM; Mein BMax-Code:Code: [AUSKLAPPEN] Function BASS_PluginGetInfo:Byte Ptr(handle:Int)
Type BASS_PLUGININFO Field version:Int Field formatc:Int Field formats:BASS_PLUGINFORM[] EndType Type BASS_PLUGINFORM Field ctype:Int Field name:String Field exts:String EndType Der "Aufbau des Pointer" sollte doch jetzt so aussehen: 4 Bytes: version 4 Bytes: formatc (Folgendes wiederholt sich formatc-mal) 4 Bytes: ctype n Bytes (durch 0 beendet): name n Bytes (durch 0 beendet): exts Mein Problem ist, dass ich da nur Schwachsinn herausbekomme. Werden Arrays vielleicht anders gespeichert? Haben die noch ein Byte-Prefix oder so etwas? Ich hoffe auf Antworten. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das Problem ist das Type != Struct
Ein Type hat noch einen Offset drin Pack die Type Deklarationen Mal in Extern - End Extern rein und versuchs nochma ... dann sollte es hoffentlich gehen. Wenn nicht musst du aus den Byte Ptr TBank machen und da manuell auslesen bzw. Types damit befüllen |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habs jetzt im Extern-Block.
Problem bei Extern ist aber, dass ich dass ja nicht mehr per New erstellen kann. Un bei so etwas wie Code: [AUSKLAPPEN] Local info:BASS_PLUGININFO = BASS_PluginGetInfo(plugin) gibt einen Error.
|
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das hast du recht, new kann nicht genutzt werden und sie können auch nicht extended werden.
Sie sollen ja auch von BASS zurück kommen. Du kannst von BASS erzeugte Objekte jedoch wieder an BASS zurück geben. Worum du dich jedoch selbst kümmern musst ist das sie wieder freigegeben werden. C / C++ Resourcen werden vom GC explizit nicht verwaltet. Da müsstest du dir dann ein Wrappermodul für BM Objekte machen welche intern in der Delete Methode die C / C++ Speicher wieder freigeben. Die Funktionen etc sind alle auch extern deklariert und geben den korrekten Type zurück? |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Dreamora hat Folgendes geschrieben: Sie sollen ja auch von BASS zurück kommen. Du kannst von BASS erzeugte Objekte jedoch wieder an BASS zurück geben. Das will ich ja eben nicht. Bei dem Type handelt es sich um Informationen über ein Plugin, welche ich per BlitzMax auslesen möchte.
Dreamora hat Folgendes geschrieben: Worum du dich jedoch selbst kümmern musst ist das sie wieder freigegeben werden.
Jo.
C / C++ Resourcen werden vom GC explizit nicht verwaltet. Dreamora hat Folgendes geschrieben: Da müsstest du dir dann ein Wrappermodul für BM Objekte machen welche intern in der Delete Methode die C / C++ Speicher wieder freigeben. Aber wenn ich die Daten auf die der Pointer zeigt nicht in ein Objekt reinkriege, weil der Aufbau irgendwie komisch ist, bringt mir das ja nichts.
Dreamora hat Folgendes geschrieben: Die Funktionen etc sind alle auch extern deklariert und geben den korrekten Type zurück? Die Funktion/en sind extern deklariert (Extern "win32"). Die Funktion, um die es geht gibt einen Byte Ptr zurück. (Siehe erster Post)
EDIT: Hab mal die Funktionsdeklaration geändert: Code: [AUSKLAPPEN] Function BASS_PluginGetInfo:BASS_PLUGININFO(handle:Int)
Wenn ich das jetzt so aufrufe (Die beiden Types sind extern):Code: [AUSKLAPPEN] Local info:BASS_PLUGININFO = BASS_PluginGetInfo(plugin)
Kommen völlig falsche Werte heraus. Außerdem wird im Debug-Bereich kein Objekt angezeigt, sondern nur das: Local info:BASS_PLUGININFO=101050cc Ausklappen, wie bei normalen Objekten ist nicht möglich. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Sicher das du Win32 zurück erhälst und nicht extern "C" nehmen müesstest?
Weil sonst kanns auch sein dass da die Calling Convention durcheinander kommt. Und du hast natürlich recht, dass du es ganz am Anfang geschrieben hast. Aber wenn du Byte Ptr zurück gibst, wird daraus niemals ein Struct werden, da müsstest du schon den Type zurück geben (dafür muss dann eben auch der Type in Extern deklariert werden). Ist mir irgendwie bis anhin net aufgefallen, sorry ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
win32 scheint richtig zu sein. Wenn ich nur extern oder extern "c" nehme, dann meldet er immer undefined reference to `BASS_Funktionsname'.
Zitat: Aber wenn du Byte Ptr zurück gibst, wird daraus niemals ein Struct werden Richtig.
Deshalb habe ich ja versucht, die Daten auf die der Pointer zeigt in ein Objekt zu kriegen. Theorethisch funktionierts ja, aber es kommen die falschen Werte heraus. Im ersten Post steht ja folgendes: Zitat: Der "Aufbau des Pointer" sollte doch jetzt so aussehen:
4 Bytes: version 4 Bytes: formatc (Folgendes wiederholt sich formatc-mal) 4 Bytes: ctype n Bytes (durch 0 beendet): name n Bytes (durch 0 beendet): exts Bis formatc kriege ich auch die richtigen ergebnisse, wenn ich einfach die ersten vier Bytes nehme, zu einem Int mache und danach den Pointer 4 Stellen weiterrücke. Aber eben beim Array liegt das Problem. Dreamora hat Folgendes geschrieben: da müsstest du schon den Type zurück geben (dafür muss dann eben auch der Type in Extern deklariert werden). Siehe mein Edit, im meinem vorherigen Post.
|
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Bin mir nicht sicher ob du extern Objekte debuggen kannst, denn sie existieren im BM nicht.
Falls die falschen Werte raus kommen, dann kannst du dran nix ändern. dann liegt es daran, dass die ersten 8 Byte von BM Types für den GC genutzt werden. Auf die kannst du jedoch noch zugreifen (object[-4] bzw. object[-8]) Die frage ist höchstens wie lange das noch geht ... diese tricks werden aktuell für verschiedene "closed module fakes" genutzt werden wo die interne referenz zerstört wird wenn die externen nimmer da sind ... Würde dir in diesem Falle jedoch definitiv eine Wrapperklasse vorschlagen die den BytePtr nimmt, die daten ausliest und sie field zuweist. entweder direkt auf dem Memory rumhacken oder TBank |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Dreamora hat Folgendes geschrieben: Würde dir in diesem Falle jedoch definitiv eine Wrapperklasse vorschlagen die den BytePtr nimmt, die daten ausliest und sie field zuweist.
Irgendwie denken/reden wir ein bissel aneinander vorbei. entweder direkt auf dem Memory rumhacken oder TBank ![]() Wie im ersten Post steht ging es mir ja eigentlich darum, so eine Art Wrapper zu schreiben, eben indem ich den Speicher auf den der Pointer zeigt durchgehe und die Daten in das BMax-Objekt kloppe. Das scheitert aber an dem Array. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das ist kein Wrapper sondern wäre direkter Struct Import
Was du machen musst wär das hier: (auf Basis dessen geschrieben was du im ersten Posting reingepackt hast, weiss net obs geht) Code: [AUSKLAPPEN] Extern function BASS_PluginGetInfo:Byte Ptr( handle:int) end extern Type BASS_PLUGININFO field version:int field formatc:int field formats:BASS_PLUGINFORM[] method fillFromMemory(data:byte ptr) local count:int = 0 version = data[count] count :+ 4 formatc = data[count] count :+ 4 local temp:BASS_PLUGINFORM local list:TList = new TList local i:int = 0 while (count < sizeof(data)) temp = new BASS_PLUGINFORM temp.ctype = data[count] count :+ 4 temp.name = string.fromcstring(data[count]) ' alternativ data + count count = temp.name.length + 1 temp.exts = string.fromcstring(data[count]) ' alternativ data + count count = temp.name.length + 1 list.addlast(temp) wend formats = new BASS_PLUGINFORM[list.count] for temp = eachin list formats[i] = temp i :+ 1 next end method End Type Type BASS_PLUGINFORM field ctype:int field name:string field exts:string End Type hab nicht getestet, potentiell sollte es so gehen. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm, das kann nicht klappen, da Sizeof ja die Größe eines Objekttyps zurückgibt, bei Byte Ptr immer 4. Man bräuchte eine Funktion, die die Größe des Speichers zurückgibt, auf die der Pointer zeigt. | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group