Comment utiliser Crtl dans une unité Delphi dans un projet C ++ Builder? (Ou lien vers C ++ Builder bibliothèque d'exécution C)

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

  •  24-10-2019
  •  | 
  •  

Question

J'ai une unité Delphi qui est un lien statique fichier d'un C en utilisant la directive {$L xxx}. Le fichier C est compilé avec le compilateur de ligne de commande de C ++ Builder. Pour satisfaire les dépendances de bibliothèque d'exécution de fichier C (_assert, memmove, etc), je suis, y compris l'unité de crtl Allen Bauer mentionné ici .

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.

Si je compile cette unité dans un projet Delphi (.dproj) EVERTHING ne fonctionne correctement.

Si je compile cette unité dans un projet C ++ Builder (.cbproj) échoue avec l'erreur:

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

Et en effet, il n'y a pas un fichier crtl.obj dans le dossier d'installation de RAD Studio. Il y a un .dcu, mais pas .pas. Essayer d'ajouter crtdbg à la clause uses (l'en-tête de C où _assert est défini) donne une erreur qu'il ne peut pas trouver crtdbg.dcu.

Si je supprime les utilise clause, il échoue au lieu des erreurs qui ne figurent pas __assert et _memmove.

Alors, dans une unité Delphi dans un projet C ++ Builder, comment puis-je exporter les fonctions de la bibliothèque d'exécution C pour qu'elles soient disponibles pour relier?

Je suis déjà au courant de Rudy Velthuis article . Je voudrais éviter, si possible, puisque je l'écriture manuelle wrappers Delphi ne pas besoin d'eux dans Delphi et C ++ Builder doit déjà inclure les fonctions nécessaires.

Modifier

Pour tous ceux qui veulent jouer à la maison, le code est disponible dans le dépôt Subversion de ABRÉVIA

Était-ce utile?

La solution

Mon point de vue sur ce que vous avez seulement besoin de l'unité Delphi dans la version Delphi du projet.

Dans la version C ++ Builder vous venez de compiler et lier foolib.c comme si elle était un fichier C (il est!) Dans la version Delphi du programme que vous créez le obj avec bcc32, utilisez ctrl etc., comme décrit.

Pourquoi voulez-vous envelopper une bibliothèque C dans un emballage Delphi à consommer en C ++?

EDIT 1

Vous avez ajouté des précisions dans les commentaires.

Une autre option à envisager serait d'éviter ctrl et mettre en œuvre les fonctions manquantes dans FooWrapper. Je le fais de cette façon plutôt que d'utiliser ctrl parce que cela me donne plus de contrôle et je comprends ce qu'on appelle. Par exemple, je ne veux pas d'appels à printf() fuites dans mon application GUI ou mon DLL.

Cela peut être une option intéressante si vous manque seulement une poignée de fonctions. Souvent, la plus élégante façon de les obtenir est de les relier à partir msvcrt.dll qui est un composant système standard ces jours-ci. Bien sûr, il semble un poids lourd de bits à lien msvcrt.dll pour avoir accès à memset(), memcpy() etc.

Combien de fonctions manquantes sont là quand vous compilez l'unité Delphi sans ctrl?

EDIT 2

J'ajoute cela à la réponse à montrer un peu de code. Je propose de ma propre base de code ceci:

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. *)

Pour lien ftol I dans ftol.obj que je présume que j'extrait d'un des fichiers lib du compilateur BCC55 que je l'utilise.

Je pense que strncmp devrait être assez de routine pour mettre en œuvre dans la plaine Pascal.

sprintf est plus difficile en toute généralité, mais vous trouverez peut-être qu'il est utilisé seulement pour quelque chose de trivial comme entier en chaîne. Dans ce cas, vous pouvez truquer le code C pour appeler une routine dédiée pour cela et mettre en œuvre trivialement.

Pour être honnête avec vous, je pense « Msvcrt.dll » semble assez attrayant!

EDIT 3

Est-ce que je parle à bientôt? Vous pouvez tirer un out sprintf parfaitement utilisable de user32.dll qui presque tous les processus ont chargé de toute façon. Assurez-vous de choisir wsprintfA si c'est un version ANSI vous avez besoin.

EDIT 4

avis _beginthreadex. Vous dites que cela est défini dans une autre unité Delphi. Afin d'obtenir le compilateur de le voir, vous devez le redéclarer dans AbCtrl.pas et de là appeler la version réelle dans AbLzma.pas.

Lorsque vous incluez un obj dans le dossier Delphi le compilateur doit être en mesure de résoudre toutes les références dans le fichier .obj à partir de l'unité Delphi qui des liens vers l'obj. Ce jeu entier est traité par le compilateur plutôt que l'éditeur de liens.

Parfois, vous emmêler dans les noeuds avec l'ordre dans lequel vous incluez les fichiers OBJ et la solution est d'utiliser des déclarations vers l'avant, mais c'est une autre histoire.

Autres conseils

Dans ce cas, les fonctions qui vous intéressent sont censées être disponibles directement à partir du C RTL, alors truquer le linker avec un mannequin (vide) obj fichier devrait fonctionner comme il satisfera l'éditeur de liens à la recherche du fichier obj qui Delphi a dit qu'il vous faut, mais toujours trouver les fonctions dans le RTL.

Late, mais plus complète: crtl.dcu fonctionne sans problèmes de D2005 jusqu'à jusqu'à XE2.

Pour D6 et D7 il y a une dépendance à l'égard midaslib.dcu. Eh bien, pas vraiment, le DCU est distribué avec une clause uses de sales.

Pour D6 et D7 vous devez créer un midaslib.pas VIDES de substitution, comme:

unit midaslib;
interface
implementation
end.

Maintenant, vous pouvez utiliser crtl.dcu sans les erreurs internes!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top