Arrays in Types

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Vertex

Betreff: Arrays in Types

BeitragSa, Jan 29, 2005 19:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Folgendes Problem:
Normalerweise kann ich ja ein Array in einem Type so definieren:
Code: [AUSKLAPPEN]
Type TMyType
   Field iIrgendwas:Int
   Field bBlub:Byte[256]
   Field sFoo:String
End Type


Das Problem ist aber, das BMax daraus folgenden Type macht:
Code: [AUSKLAPPEN]
Type TMyType
   Field iIrgendwas:Int
   Field Pointer auf bBlub
   Field Pointer auf sFoo
End Type


Bei dem String ist das ganze ja noch verständlich, da sich die Länge des Strigns ändern kann. Bei dem Array hingegen finde ich das ganze nichtmehr so lustig, da ich eindeutig die größe mit 256 Byte festlege denn ich sage ja nicht bBlub:Byte[] und die Größe dann ersteinmal unbestimmt lasse, bis ich New einsetze.

Der Type sollte intern so aussehen:
Code: [AUSKLAPPEN]
Type TMyType
   Field iIrgendwas:Int
   Field bBlub[0]:Byte
   Field bBlub[1]:Byte
   Field bBlub[2]:Byte
   Field bBlub[3]:Byte
   ...
   Field bBlub[255]:Byte
   Field sFoo:String
End Type


Gibt es da irgendwie eine Lösung, denn viele C-Strukturen haben feste Arraygrößen für Strings.

mfg olli
vertex.dreamfall.at | GitHub

eizdealer

BeitragSa, Jan 29, 2005 20:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Wo liegt denn das Problem, außer einem leicht anderen Handling?
Die 'Variable' bBlub[X] ist schließlich kein Pointer mehr, da sie dereferenziert wurde. Vielleicht kannst du kurz beschreiben, was du machen willst und wie du damit nicht weiterkommst (falls das überhaupt der Fall ist).

Vertex

BeitragSa, Jan 29, 2005 22:01
Antworten mit Zitat
Benutzer-Profile anzeigen
http://www.c-worker.ch/dokuwsc...htm#4.3.15

Die Funktion in BMax einbinden geht so:
Code: [AUSKLAPPEN]
Extern "Os"
   Function s_WSAStartup:Int(shVersion:Short, tWSA:Byte Ptr) = "WSAStartup@8"
   Function s_WSACleanup:Int() = "WSACleanup@0"
End Extern


Die Typedefinition habe ich mal so gestaltet:
Code: [AUSKLAPPEN]
Type TWSAData
   Field shVersion:Short
   Field shHighVersion:Short
   Field bDescription:Byte[256+1]
   Field bSystemStatus:Byte[128+1]
   Field shMaxSockets:Short
   Field shMaxUdpDg:Short
   Field pbVendorInfo:Byte Ptr
End Type


Was natürlich falsch ist...

(Ich muss das ganze in der Funktion als Byte Ptr definieren, und kann nicht sagen tWSA:TWSAData)

Code: [AUSKLAPPEN]
#include <windows.h>

int main(void)
{
  printf("%d %s \n", sizeof(WSADATA), "Byte");
  system("PAUSE");   
  return 0;
}


Gibt mir "400 Byte" aus...

Code: [AUSKLAPPEN]
Type TWSAData
   Field shVersion:Short
   Field shHighVersion:Short
   Field bDescription:Byte[256+1]
   Field bSystemStatus:Byte[128+1]
   Field shMaxSockets:Short
   Field shMaxUdpDg:Short
   Field pbVendorInfo:Byte Ptr
End Type

Local tWSA:TWSAData
 
Print SizeOf(tWSA)+" Byte"


Gibt mir "20 Byte" aus.
(Warum SizeOf(TWSAData) mir 4 Byte ausgibt, ist auch so eine Sache, event wall es als Funktionspointer angesehen wird, da man mit TWSAData(Objekt) prüfen kann, ob es vom selben Typ ist)

Naja jedenfalls steht dann der Systemstatus eigentlich in dem 129 Byte großen Array, jedoch wird das Array als Pointer behandelt, was nur bei C-Strings mit char* Sinn macht. Was auch scheiße ist, das Strings in types, wenn man sie einer externen Funktion übergibt, als Blitz-Strings übergeben werden, und nicht als C-Strings(schließlich funzt das ja bei Parameterübergabe an eine externe Funktion auch).

mfg olli
vertex.dreamfall.at | GitHub

TheShadow

Moderator

BeitragSo, Jan 30, 2005 13:24
Antworten mit Zitat
Benutzer-Profile anzeigen
in C sind diese arrays auch nur pointer... vielleicht passt sizeof nich oder k.a....
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
 

Serge

BeitragSo, Jan 30, 2005 13:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Mal etwas OT:
Arrays können in Bmax also dynamisch sein? Also verschiedene größen Annehmen?

field test:string[]

hätte zu beginn eine größe von null und mit

test[3]="blabla"

Eine größe von 4?
(bzw. später test[5]="hu" eine größe von 6?)
Oder wie funktioniert das?
http://www.dark-matter-soft.de

Vertex

BeitragSo, Jan 30, 2005 17:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
Const SOCKET_ERROR = -1

Extern "Os"
   Function s_WSAStartup:Int(shVersion:Short, tWSA:Byte Ptr) = "WSAStartup@8"
   Function s_WSAGetLastError:Int() = "WSAGetLastError@0"
   Function s_WSACleanup:Int() = "WSACleanup@0"

   Function MemCopy2(dest:Byte Ptr, src:Int, size:Int) = "bbMemCopy"
End Extern

Function MAKESHORT:Short(bA:Byte, bB:Byte)
   Return bA | (bB Shl 8)
End Function

Local tWSA:TBank
Local iIndex:Int
Local bChar
Local sDescription:String
Local sSystemStatus:String
Local pVendorinfo:Byte Ptr

tWSA = CreateBank(400)
Print "Starte Winsock..."
If s_WSAStartup(MAKESHORT(2, 0), BankBuf(tWSA)) = SOCKET_ERROR Then
   Print "Fehler: "+s_WSAGetLastError()
Else
   Print "OK"
EndIf


For iIndex = 4 To 260
   bChar = PeekByte(tWSA, iIndex)
   If bChar = 0 Then Exit
   sDescription = sDescription+Chr(bChar)
Next

For iIndex = 261 To 393
   bChar = PeekByte(tWSA, iIndex)
   If bChar = 0 Then Exit
   sSystemStatus = sSystemStatus+Chr(bChar)
Next

Print "Version:      "+PeekShort(tWSA, 0)
Print "HighVersion:  "+PeekShort(tWSA, 2)
Print "Description:  "+sDescription
Print "SystemStatus: "+sSystemStatus
Print "MaxSockets:   "+Peekshort(tWSA, 394)
Print "MaxUdpDg:     "+PeekShort(tWSA, 398)

Print "Beende Winsock..."
If s_WSACleanup() = SOCKET_ERROR Then
   Print "Fehler: "+s_WSAGetLastError()
Else
   Print "OK"
EndIf

Release tWSA ; FlushMem
Delay 2000
End


TheShadow: Wie du siehst, werden nicht die Pointer, sonder deren Inhalte der Arrays in die Strukturen untergebracht. (obwohl ich mir nicht erklähren kann, warum MaxSockets um 4 Byte im Offset verschoben wird)

Serge:
Code: [AUSKLAPPEN]
Local sText:String[]

sText = New String[0]
Print SizeOf(sText)

Release sText
sText = New String[1]
Print SizeOf(sText)

Release sText
sText = New String[2]
Print SizeOf(sText)

Release sText
sText = New String[3]
Print SizeOf(sText)


Wie du siehst nimmt ein Eintrag 4 Byte weg. Warum? Weil Strigns dyn. Längen annehmen können, und somit nur die Pointer der Strings in die Arrays abgespeichert werden. Andernfalls müsste man die ganzen anderen Einträge immer pro Änderung eines Strings verschieben was sau viel Perfomenceverlust bedeuten würde.

Du musst unbedingt Release anwenden, bevor du ein Array neu dimensionierst. Das liegt daran, das neuer Speicher hergeholt werden muss, was bedeutet, das der Alte Speicher ohne Release vor sich ungenutzt im RAM herumgeammelt. Die alten Einträge gehen dadurch natrülich verloren, denn neuer Speicher bedeutet neue Addresse. Du kannst aber ein Temparray erstellen, wo du die alten Einträge in dieses Array kopierst, das alte löschst und neu dimensionierst, das Temparray in das neue kopierst und dann das Temparray löschst. So macht das BMax z. B. auch bei ResizeBank.

mfg olli
vertex.dreamfall.at | GitHub

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group