Problem bei Pascal zu C Konvertierung
-
Ahoi.
Ich möchte ein Delphi Programm in CBuilder umschreiben und scheiter entweder an meinem schlechten C Wissen oder dem noch viel geringeren Pascal verständnis
Ich bekomme immer EInvalidPointer MessageBoxen... Ich denke mal es liegt an den Zeilen.
tRecord = Record Var1 : Word; Var2 : Byte; Var3 : Byte; end; tRecordArray = array[1..300] of tRecord; pByteMatrix = ^tByteMatrix; tByteMatrix = array[1..300, 1..300] of Byte; // in Funktion pRes : pByteMatrix; tRes : tByteMatrix; SubArray : tRecordArray; // Funktion schreibt in pRes Daten und übergebe dann an... tRes := pRes^;
Mein C
struct tRecord { Word Var1; byte Var2; Byte Var3; }; typedef tRecord tRecordArray[300]; typedef Byte tByteMatrix[300][300]; typedef tByteMatrix *pByteMatrix; // in Funktion tRecordArray SubArray; pByteMatrix pRes = NULL; tByteMatrix *tRes; // Funktion schreibt in pRes Daten und übergebe dann an... tRes = pRes;
Stimmt das?
-
tRes ist ja kein Zeiger, die letzten Zeilen sollten also so sein:
tByteMatrix tRes; tRes = *pRes;
Allerdings weiß ich nicht ob C++ das ganze Array kopiert kann
-
Ups vergessen. Allerdings ist diese Zeile an recht weit unten im Pascal Programm und soweit bin ich noch net gewesen. Nur Vollständigkeitshalber hinzugefügt. Aber sonst alles ok?
-
Hi!
Das hier sollte dem schon näher kommen:
struct tRecord { unsigned integer Var1; // Es gibt weder Word noch Byte in C++ unsigned short Var2; unsigned short Var3; }; typedef tRecord tRecordArray[300]; typedef unsigned short tByteMatrix[300][300]; typedef tByteMatrix *pByteMatrix; // in Funktion tRecordArray SubArray; pByteMatrix pRes; tByteMatrix tRes; // Dies soll kein Zeiger sein
Wegen dem Array, das musst du rüberkopieren über 2 ineinanderverschachtelte Schleifen, etwa so:
for(int i=0; i<300; ++i) for(int j=0; j<300; ++j) tPes[i][j] = (*pRes)[i][j]; // Ich glaube die Zuweisung stimmt so nicht ganz
Code-Hacker
-
typedef unsigned short tByteMatrix[300][300]; typedef tByteMatrix *pByteMatrix; pByteMatrix test; *test[0][1] = 5; Caption = *test[0][1];
So compiliert er es, aber stürzt in der Zeile mit "*test[0][1] = 5;" ab.
Ich vermute das es daran liegt das nirgends ein fester Speicherbereich festgelegt wurde.wenn ich
float x,wert=1.23; memcpy(&x,&wert,4);
sürtzt das programm auch ab.. sobald ich aber float x=0.0; setze würde es korrekt laufen.
Wie muss ich oben einen Speicherbereich reservieren?
-
Hi!
Ich weiß ja nicht wie das bei Pascal bei mehrdimensionalen Arrays mit der Speicherreservierung funktioniert, aber in C++ müsste das etwa so aussehen:
typedef unsigned short *pByteMatrix[300] pByteMatrix (*pRes)[300] = new unsigned short[300][300];
Jetzt kannst du wie du es gemacht hast darauf zugreifen, nur denk daran später den Speicher wieder freizugeben.
Zum Absturz:
Das passiert, weil du 300*300 Zeiger hast die leider nirgendwohin zeigen, du musst also Speicher dafür reservieren.Code-Hacker
-
Ja da gebe ich dir Recht. Wundert mich nur das Pascal besser mit Zeigern umgehen kann als C
Leider funktioniert dein Beispiel nicht
[C++ Fehler] main.cpp(67): E2034 Konvertierung von 'unsigned short ( *)[300]' nach 'unsigned short * ( *)[300][300]' nicht möglich
-
Hi!
Sorry, ähm so müsste es richtig sein:
typedef unsigned short *pByteMatrix[300] pByteMatrix pRes = new unsigned short[300][300];
Ich habe das eben aus nem anderen Thread hier im Forum kopiert und dabei nicht aufgepasst das ich das bei der deklaration ja nicht mehr benötige.
Wieso kann Pascal besser mit Zeigern umgehen als C++? Eigentlich musst du auch in Pascal Speicher reservieren für einen Zeiger um diesen benutzen zu können. Pascal bietet oft eine kurze Schreibweise an, wie bei der Zuweisung oben zu sehen ist, wo du einfach dereferenzierst und an das Array zuweist, das ist in C++ so nicht möglich, da brauchst du schon eine Schleife und musst jedes Element kopieren. In C++ würdest du so allerdings die Adresse an einen anderen Zeiger zuweisen und dann mit diesem ebenfalls auf das Array zugreifen, es wäre dann aber nicht kopiert.
Code-Hacker
-
Sorry das ich dich in atem halte. Aber auch das klappt so nicht
Habe mal doof rumgespielt und das klappt scheinbar nun
Danke für deine Hilfe!typedef unsigned short tByteMatrix[300][300]; typedef tByteMatrix *pByteMatrix; pByteMatrix pRes = new tByteMatrix[300];
-
Hi!
Jo, programmiere momentan kein C++. Bin nur wieder etwas aktiv, damit ich mich wieder etwas einarbeiten kann und mal Abwechslung zum schreiben von Shellskripten habe.
Code-Hacker
-
Ich greife auf eine Funktion namens Check() aus einer Delphi DLL zu..
Mit Delphi Code:pByteMatrix = ^tByteMatrix; tByteMatrix = array[1..MAX, 1..MAX] of Byte; //-------- pRes : pByteMatrix; pRes := nil; CheckError := Check(pRes, count, SubArray);
count ist die Anzahl von den Elementen aus SubArray was ein record ist.
in pRes steht letztendlich ein aufgefülltes Array.. soll es zumindest.In meinem Code:
typedef unsigned short tByteMatrix[MAX][MAX]; typedef tByteMatrix *pByteMatrix; //--------- pByteMatrix pRes = new tByteMatrix[MAX]; pRes = NULL; CheckError = Check(pRes, max, SubArray);
Starte nun EXE...
Wemm er zu der Check() Funktion kommt meldet eine Messagebox "Zugriffsverletztung". Wenn ich es aus der Entwicklung starte (CBuilder5) dann verlangt er plötzlich wenn ich auf den Check-Button drücke eine .dpr Datei zu dem DLL Namen. Ich bin echt am Ende der Fahnenstange.Ich hasse Delphi
-
Arrays sind in C ganz schön kaputt, und C++ hat mit new[] und delete[] nochmal ordentlich einen draufgesetzt. Am einfachsten umgeht man solche Probleme immer, indem man das Array in eine struct verpackt (das ist noch sicherer als ein typedef):
struct ByteMatrix { int values[300][300]; };
Übergeben könntest du das Ganze dann z.B. so:
void fill(ByteMatrix& ziel) { ziel[5][2] = 6; // usw., hier wird das Array ausgefüllt } ... ByteMatrix bm; // Einfach auf dem Stack erstellen fill(bm);
Du könntest natürlich auch mit new/delete arbeiten (dank dem struct wie mit jedem anderen Datentyp auch) - aber das sind dann alles Grundlagen, die nichts mehr mit Arrays zu tun haben.
-
Das heisst dann aber
void fill(ByteMatrix& ziel) { ziel.values[5][2] = 6; }
Auf jedenfall ein super Vorschlag für andere Proekte.
Mein Problem hier ist nur, das ich eine DLL habe und eine Schnittstellenbeschreibung in Pascal. Ich muss ja gleiche Datentypen verwenden.
Also irgendwie find ich das Pascalteil extrem doof gemacht. Oder ich bin nur zu doof dafür.