Einzelnen Beitrag anzeigen

Benutzerbild von Mastersargon
Mastersargon

Registriert seit: 18. Dez 2009
4 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: realloc in C-Dll schlägt fehl bei Aufruf von Delphi IDE

  Alt 18. Dez 2009, 23:30
Hallo Astat!

Danke für Deine schnelle Antwort! Dein Vorschlag ist in der Tat eine äquivalente Alternative, nur leider besteht das gleiche Problem fort. Der Char (packet) wird angelegt, dessen Adresse (richtig) übergeben, aber eine Speichervergrößerung zum Char-Reihung scheitert...

Die data_len / packet_len Variablen (ob DWord, LongInt oder LongWord bzw. Zeiger darauf - je nach Aufruf) werden korrekt angenommen und verarbeitet. Die Frage ob Byte oder Char: das ist nur eine Darstellungsfrage.
Zusätzlich habe ich in der C-Funktion dafür gesorgt, daß die Speichergröße von packet um 1 größer als packet_len ist und das letzte Zeichen ein #0 ist, um bei einem typecast mit PChar() nicht auf die Nase zu fallen.
Auch Die Zeigeradressen von packet vor und nach der Reallokation sind gleich, sofern ich vorher schon genügend alloziere und nicht in der IDE starte... Überhaupt frage ich mich, warum mit Start in der IDE solche Probleme entstehen können. Kann es sein, daß Delphi ein "Hineinpfuschen" nicht gerne sieht?

Hier der Ausschnitt der C-Funktion:

Code:

// ...

typedef unsigned char byte; // 8 Bit, unsigned
typedef unsigned short word; // 16 Bit, unsigned
typedef unsigned long int dword; // 32 Bit, unsigned

// ...

// Globale Variable:

dword preamblelen = 6; // Zum Beispiel...

// ...

__declspec (dllexport) byte* send(const dword* data_len, const byte* data, dword* packet_len, byte* packet) {
  dword lc;
  word coded_;
  word* coded = &coded_;
  *packet_len = preamblelen + 1 + *data_len * 2;
  // 3 Zeilen für Debuging   
  // char msg[100];
  // sprintf(msg, "dl = %d, pl = %d, adr(d) = 0x%x, adr(p) = 0x%x, d = %s, p = %s", *data_len, *packet_len, data, packet, data, packet);
  // MessageBox (0, msg, "2", MB_ICONINFORMATION);
  packet = (byte*) realloc(packet, (*packet_len + 1) * sizeof(byte)); // <---------------- Dies ist die kritische Stelle
  if (packet == NULL) {
    // MessageBox (0, "Reallocation of Memory failed!\n", "Error!", MB_ICONINFORMATION);
    exit(EXIT_FAILURE);
  }
  else { 
    // ... // soweit kommt es nicht mehr...
  }
}
Dieser Code (Delphi Testprogramm) funktioniert - wie gesagt, jedoch nicht wenn er in der IDE gestartet wird:

Delphi-Quellcode:

// Globale Variablen:

  dl, pl : LongWord;
  ds, ps : ShortString;
  dc, pc : Char;
  dpc, ppc : PChar;
  preamble_len: LongWord; // Im Quelltext mit einem konstanten Wert initialisiert

// ...

PROCEDURE TForm1.Button1Click(Sender: TObject);
BEGIN
  dl := Length(Edit1.Text); // In Edit 1 steht: 'Edit1'
  pl := preamble_len + 2 + dl * 2; // Precalculate size of packet length
  ds := Edit1.Text;
  dpc := PChar(ds);
  ppc := AllocMem(pl); // Wenn ich hier nicht bereits den Speicher alloziere, klappt es nicht :(
  //ppc := dummy(dl, dpc, pl, ppc);
  ppc := dcpml_send(dl, dpc, pl, ppc); // bei der alten Deklaration, siehe 1. Post oben
  ps := String(ppc);
  Edit2.Text := ps;
END;
Übrigens habe ich die fragliche Funktion im Prinzip (als dummy-Funktion) in Delphi nachgebildet und dort auch ReallocMem genutzt. Da klappt es ohne weiteres...

Jetzt müßte ich nur noch herausfinden, wie es ohne vorherige Allokation in Delphi geht...

Grüße!
  Mit Zitat antworten Zitat