AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Fehler in Record-Ausrichtung bei Übergabe an Visual C DLL
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler in Record-Ausrichtung bei Übergabe an Visual C DLL

Ein Thema von oki · begonnen am 30. Dez 2002 · letzter Beitrag vom 5. Jan 2003
Antwort Antwort
Seite 1 von 3  1 23      
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#1

Fehler in Record-Ausrichtung bei Übergabe an Visual C DLL

  Alt 30. Dez 2002, 17:09
Hallo,

ich hab hier ein ganz blödes Problem. Für ein aktuelles Projekt rufe ich Methoden aus einer Dll mit Parameterübergabe mittels Zeiger auf Strukturen auf. Hierbei bekomme ich sporadisch Lesefehler auf Adressen aus der DLL.
Nach einem Gespräch mit dem Ersteller der DLL habe ich folgenden Tip überprüft.
Die DLL ist in Visual C geschrieben und erwartet eine 8 Byte Ausrichtung für Structuren (Records) im Speicher.
Nun richtet Delphi in der Regel an 32 Bit (4 Byte) Grenzen aus.
Somit habe ich den notwendigen Speicher mit GlobalAlloc reserviert (hier soll nach SDK auf jeden Fall an 8 Byte Grenzen ausgerichtet werden).
Jetzt mußte ich feststellen, dass meine Recordausrichtung zwar auf 32 Bit erfolgt, aber der Lesefehler trotzdem bleibt. Nach mühsammen debuggen mußte ich feststellen, dass mit dem Methodenaufruf aus der DLL die Structure an eine Speicherstelle kopiert wird die nicht an 8 Byte Grenzen ausgerichtet ist.

Jetzt kommt der absolute Spaß!!!!!!!!!

Füge ich in meinem Quellcode zusätzliche Codezeilen ein (müssen nichts mit benannter Structure zu tun haben) klappt auch mall alles prima.

Was ist da los?

Wie kann ich meinen Compiler überreden Speicher automatisch an 8 Byte Grenzen auszurichten? Ich bin hier aktuell etwas hilflos und finde zu diesem Thema keine vernünftigen Info's.

Ach ja, ich benutze Delphi 5 Enterprise.

Gruß oki.
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.412 Beiträge
 
Delphi 12 Athens
 
#2
  Alt 30. Dez 2002, 17:15
Einfach an den Anfang der Units, welche es betrifft
Code:
{$ALIGN 8}
einfügen. Wenn der Compiler das nicht schluckt, dann hast Du leider Pech. Der Schalter ist in D7 beschrieben, ob D5 den schon hat, ich glaube leider nicht.
Daniel Lizbeth
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Brüggendiek

Registriert seit: 13. Dez 2002
Ort: Dortmund
275 Beiträge
 
Delphi 5 Standard
 
#3
  Alt 30. Dez 2002, 17:23
Hallo!

Zitat von sakura:
Der Schalter ist in D7 beschrieben, ob D5 den schon hat, ich glaube leider nicht.
D5 Standard kennt nur {$ALIGN ON} / {$A+}: Record-Werte ausrichten bzw. {$ALIGN OFF} / {$A+}: Record-Werte nicht ausrichten, also alle RECORDs als PACKED speichern. Voreinstellung: {$A+}.

Leider!

Gruß

Dietmar Brüggendiek
Dietmar Brüggendiek
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#4
  Alt 30. Dez 2002, 19:25
Moin Oki,

also dass man auf Grund eines falschen Alignments CPU Strafzyklen erhält hab' ich ja schon gehört, aber das die Daten auf eine bestimmte Adresse ausgerichtet sein müssen, damit der Zugriff überhaupt erfolgen kann ist mir neu.

Diese Ausrichtung soll ja eigentlich nur dafür sorgen, dass die CPU das Programm schneller abarbeiten kann, wenn die Daten an einer Grenze liegen die der generischen Adressbus Breite der CPU entspricht, was bei einem 8 Byte Alignment ja eindeutig auf eine 64 Bit CPU hindeutet.

Ausser die DLL geht mit übergebenen Pointern sehr eigenwillig um ( ) dürfte das nicht zu einem Fehler führen, sondern schlimmstenfalls zu einer langsameren Abarbeitung des Programmes.

Kann es sein, dass der von Dir benutzte Record als record und nicht als packed record deklariert ist?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#5
  Alt 30. Dez 2002, 19:51
Erst mal herzlichen Dank für die schnellen Antworten.

Leider stimmt es, dass D5 die Direktive ALIGN 8 nicht kennt. Ich werde es trotzdem einfach mal probieren.

Leider ist es wirklich so, dass die Daten an einer 8 Byte Ausrichtung erwartet werden. Ich habe es im Debuger geprüft. Bei einem Versatz der Structure um 4 Byte im Speicher wird beim kopieren das erste DWord einfach ignoriert. Mein Kontakt hat mir außerdem berichtet, dass Visual C mit Sicht auf 64 Bit-Processoren grundsätzlich eine 64 Bit-Ausrichtung erwartet.
Ob das alles so korrekt ist weiß ich nicht. Vielleicht ist die Speicherbearbeitung auch wieder einmal so'n komisches C-Programmiererteil.
Mein Problem ist aber nachweisbar das beschriebene.

Vieleicht hat ja noch einer 'ne Idee.

Bis dann Olaf
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#6
  Alt 31. Dez 2002, 00:48
Moin Olaf,

Zitat:
dass Visual C mit Sicht auf 64 Bit-Processoren grundsätzlich eine 64 Bit-Ausrichtung erwartet.
Also ich kann mir vorstellen, dass das als Defaulteinstellung gilt, aber nicht, dass es unabänderlich ist. (hab' leider gerade keine VC zur Hand)

So wie es aussieht scheint's da wohl nur zwei Lösungsansätze zu geben:
  1. Du steigst auf D7 um damit Du die DLL sicher benutzen kannst. (wenn's denn mit Align 8 wie gewünscht geht)
  2. Die DLL wird mit 32 Bit Alignment neu kompiliert.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#7
  Alt 31. Dez 2002, 15:33
Hallo Christian,

Dank für die Antwort. Ich werd mal versuchen den C-Programmierer zu beschwatzen mir ein neues Compiling zu schicken bevor ich Geld für D7 in die Hand nehme.

Gruß Olaf
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#8
  Alt 31. Dez 2002, 16:55
Kannst du nicht einfach die struct, Verzeihung, den record packed machen und die zur 8-Byte-Ausrichtung fehlenden Bytes einfach als leere Bytes hinzufügen? Wenn ich das Problem richtig verstanden habe , müsste das doch so gehen...

Leider kann man zumindest in VC6.01 SP4 nur 1 bis 16 Byte als struct-Elementausrichtung einstellen...
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#9
  Alt 31. Dez 2002, 18:45
Moin Oregon Ghost,

wenn eine Ausrichtung von 1 bis 16 einstellbar ist, ginge doch auch 4 oder nicht?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#10
  Alt 1. Jan 2003, 18:36
Hallo ihr alle zusammen.

Für mein erstes Problem habe ich eine Lösung gefunden (der erste Eindruck ist jedenfalls so). Ich habe für den Record einfach ausreichend Speicher mittels GlobalAlloc auf einen Zeiger vom Typ PChar reserviert. Laut SDK soll GlobalAlloc Adressen in einer 8 Byte-Ausrichtung reservieren. Die entsprechenden Einträge habe ich dann mittels move-Befehl an die entsprechende Stelle Zeiger[x] kopiert.
Das sah alles erstmal richtig gut aus.

Ergebnis der Aktion -----------> Fehlermeldung aus der DLL!!!

Jetzt habe ich mich mühsam mittels CPU-Debugger durch den Code gequält und folgendes festgestellt.
Mein Record wird ordnungsgemäß angelegt und an die DLL-Methode übergeben. Die DLL-Methode legt einen eigenen Speicherbereich an der aber jetzt nicht an einer 8 Byte Grenze ausgerichtet ist!!!! Jetzt wird mein Speicherinhalt mit einer Ausrichtung an einer 8 Byte-Adresse in diesen Speicher kopiert. Somit entsteht ein Versatz von 4 Byte.

Jetzt kommt meine doofe Frage:

Das passiert doch alles in der DLL. Was habe ich damit zu tun?
Muscht der Delphi-Compiler irgentwo rum, dass der an die Basisadresse geladene DLL-Code Mist baut?
Ich weiß, dass sich das jetzt alles ganz schön blöd anhört, aber ich habe C-Beispielcode bekommen, bei dem alles super mit der DLL klappt.

Vielleicht hat ja noch einer eine Idee.

Übrigens vielen Dank für die Tips mit dem Auffüllen und den packed record's. Hab ich leider vorher schon probiert (sicher erfolglos weil das Problem woanders steckt).

Gruß Olaf
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz