Wie verwenden Sie Strg in einer Delphi-unit, die in einem C++Builder-Projekt?(oder link zu C++Builder-der C-Laufzeit-Bibliothek)

StackOverflow https://stackoverflow.com/questions/5303568

  •  24-10-2019
  •  | 
  •  

Frage

Ich habe eine Delphi-unit, die die statische Verknüpfung a C .obj-Datei mit der {$L xxx} Richtlinie.Die C-Datei kompiliert, die mit C++Builder command line compiler.Zu erfüllen die C-runtime-Bibliothek-Abhängigkeiten (_assert, memmove, etc), ich bin auch der crtl Einheit Allen Bauer erwähnt hier.

unit FooWrapper;

interface

implementation

uses
 Crtl; // Part of the Delphi RTL

{$L FooLib.obj}  // Compiled with "bcc32 -q -c foolib.c"

procedure Foo; cdecl; external;

end.

Wenn ich kompilieren, die Einheit in ein Delphi-Projekt (.dproj) alles ordnungsgemäß funktioniert.

Wenn ich kompilieren, die Einheit, die in einem C++Builder-Projekt (.cbproj) schlägt es fehl, mit der Fehlermeldung:

[ILINK32 Error] Fatal: Unable to open file 'CRTL.OBJ'

Und in der Tat gibt es nicht crtl.obj Datei in die RAD Studio-Installation Ordner.Es ist ein .dcu, aber Nein .pas.Versuchen Sie auf hinzufügen crtdbg der uses-Klausel (der C-header, wo _assert definiert ist) gibt einen Fehler, dass es nicht finden kann crtdbg.dcu.

Wenn ich entfernen Sie die verwendet Klausel, die es stattdessen schlägt fehl mit Fehlern, die __assert und _memmove nicht gefunden.

So, in einer Delphi-unit, die in einem C++Builder-Projekt, wie kann ich export-Funktionen aus der C-Laufzeit-Bibliothek, Sie sind also für die Verknüpfung verfügbar sein?

Ich bin mir schon bewusst, Rudy Velthuis s Artikel.Ich möchte nicht manuell schreiben von Delphi-Wrapper, wenn möglich, da ich Sie nicht brauchen in Delphi und C++Builder müssen enthalten bereits die notwendigen Funktionen.

Bearbeiten

Für alle, die will zu spielen, zusammen zu Hause, der code ist im Abbrevia das Subversion-repository auf https://tpabbrevia.svn.sourceforge.net/svnroot/tpabbrevia/trunk.Ich habe David Heffernan Beratung und fügte hinzu, eine "AbCrtl.pas" Einheit, ahmt Strg.dcu beim kompilieren in C++Builder.Das hat der PPMd-support funktioniert, aber Sie die Lzma-und WavPack-Bibliotheken sowohl fehl mit Fehler:

[ILINK32 Error] Error: Unresolved external '_beginthreadex' referenced from ABLZMA.OBJ
[ILINK32 Error] Error: Unresolved external 'sprintf' referenced from ABWAVPACK.OBJ
[ILINK32 Error] Error: Unresolved external 'strncmp' referenced from ABWAVPACK.OBJ
[ILINK32 Error] Error: Unresolved external '_ftol' referenced from ABWAVPACK.OBJ

AFAICT, alle von Ihnen sind korrekt deklariert, und die _beginthreadex tatsächlich erklärt in AbLzma.pas, so es ist verwendet durch die Reine Delphi kompilieren als gut.

Sehen Sie es selbst, laden Sie einfach die Stamm (oder einfach nur die "Quelle" und "Pakete" - Verzeichnisse), deaktivieren Sie die {$IFDEF BCB} - block an der Unterseite der AbDefine.inc., und versuchen Sie zum kompilieren von C++Builder "Abbrevia.cbproj" - Projekt.

War es hilfreich?

Lösung

Meine Meinung dazu ist, dass Sie nur noch die Delphi-unit in der Delphi-version des Projekts.

In die C++ builder-version, die Sie kompilieren und verknüpfen foolib.c als ob es war eine C-Datei (es ist!) In der Delphi-version das Programm, das Sie erstellen .obj mit bcc32, verwenden Sie Strg etc.wie beschrieben.

Warum wollen Sie es einpacken eine C-Bibliothek in Delphi wrapper, die konsumiert werden, die in C++?

BEARBEITEN 1

Die Sie Hinzugefügt haben, Klarstellungen in die Kommentare.

Eine weitere option zu prüfen wäre, zu vermeiden, Strg und implementieren Sie die fehlenden Funktionen in FooWrapper.Ich mache das Weg, anstatt Strg, weil das gibt mir mehr Kontrolle, und ich verstehe, was aufgerufen wird.Für Beispiel, ich will keine Anrufe an printf() leckt in meine GUI app oder meine DLL.

Dies könnte eine attraktive option sein, wenn Sie sind fehlt nur noch eine Handvoll von Funktionen.Oft ist der sauberste Weg, um Sie zu verknüpfen, Sie in aus msvcrt.dll was ist ein standard-system-Komponente in diesen Tagen.Natürlich scheint es ein bisschen Schwergewicht auf den link in msvcrt.dll nur zu bekommen bei memset(), memcpy() etc.

Wie viele fehlende Funktionen gibt es beim kompilieren der Delphi-unit ohne Strg?

BEARBEITEN 2

Ich bin das hinzufügen dieser zur Antwort auf Karte code.Aus meiner eigenen code-Basis, die ich hier anbieten:

const
  __turboFloat: Longint=0;
  (* We don't actually know the type but it is 4 bytes long and initialised to zero.  This can be determined
     using tdump initcvt.obj.  It doesn't actually matter how we define this since it is ultimately not
     referred to and is stripped from the executable by the linker. *)

Für ftol I link in ftol.obj welche ich nehme an, ich zog aus einer der lib-Dateien in der BCC55 compiler, die ich benutze.

Ich denke, strncmp sollte ziemlich routine zu implementieren, die in reinem Pascal.

sprintf schwieriger ist in voller Allgemeinheit, aber Sie könnten finden, dass es nur für etwas triviales wie integer zu string.In dem Fall könnten Sie fudge, der C-code zum aufrufen einer routine-speziell für, dass und Umsetzung trivial.

Um ehrlich zu sein mit Euch, ich denke 'msvcrt.dll' sieht ganz schön attraktiv!

BEARBEITEN 3

Habe ich spreche zu schnell?Können Sie ziehen eine perfekt gewartet sprintf aus user32.dll die fast alle Prozesse sind trotzdem geladen.Stellen Sie sicher, dass Sie wählen aus wsprintfA wenn es eine ANSI-version, die Sie brauchen.

BEARBEITEN 4

Ich merke, _beginthreadex.Sie sagen, das ist definiert in eine andere Delphi-unit.Um den compiler zu sehen, müssen Sie es deklarieren es in AbCtrl.pas und von dort aus rufen Sie die echte version in AbLzma.pas.

Wenn Sie eine .obj in Delphi .pas-Datei, die der compiler muss in der Lage sein, alle zu lösen die Referenzen in der .obj-Datei aus der Delphi-unit, die links zu den .obj.Dieses ganze Spiel ist, behandelt der compiler eher als linker.

Manchmal verheddert in den Knoten mit der Reihenfolge, in der du die .obj-Dateien und die Lösung ist die Verwendung von forward-Deklaration, aber das ist eine andere Geschichte.

Andere Tipps

In diesem Fall werden die Funktionen, die Sie interessiert sind, ausgegangen werden direkt von der C-RTL, so faking out der linker mit einem dummy (leer) obj-Datei sollte so funktionieren, wie es genügen wird der linker sucht für die obj-Datei, die von Delphi sagte, müssen Sie es, aber immer noch nicht finden die Funktionen in der RTL.

Spät, aber doch mehr komplett:Strg.dcu funktioniert ohne Probleme aus D2005 bis XE2.

Für den D6 und D7 gibt es eine Abhängigkeit von midaslib.dcu.Naja, nicht wirklich, die dcu ist verteilt mit einem schmutzigen uses-Klausel.

Für den D6 und D7 erstellen Sie eine LEERE midaslib.pas Ersatz, wie:

unit midaslib;
interface
implementation
end.

Jetzt können Sie mit Strg.dcu ohne interne Fehler!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top