Bass.dll - Pointer zu einem Objekt konvertieren

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Artemis

Betreff: Bass.dll - Pointer zu einem Objekt konvertieren

BeitragFr, Jul 20, 2007 10:25
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Jul 20, 2007 10:55
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Jul 20, 2007 10:59
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Jul 20, 2007 11:30
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Jul 20, 2007 11:59
Antworten mit Zitat
Benutzer-Profile anzeigen
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.
C / C++ Resourcen werden vom GC explizit nicht verwaltet.
Jo.

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

BeitragFr, Jul 20, 2007 12:10
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Sad
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Artemis

BeitragFr, Jul 20, 2007 12:21
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Jul 20, 2007 13:31
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Jul 20, 2007 14:36
Antworten mit Zitat
Benutzer-Profile anzeigen
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.
entweder direkt auf dem Memory rumhacken oder TBank
Irgendwie denken/reden wir ein bissel aneinander vorbei. Wink

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

BeitragFr, Jul 20, 2007 15:28
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Jul 21, 2007 14:17
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group