Cómo utilizar la tecla Ctrl en una unidad en Delphi en C++Builder proyecto?(o enlace a C++Builder C runtime library)

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

  •  24-10-2019
  •  | 
  •  

Pregunta

Tengo una unidad en Delphi que es enlazar estáticamente C .obj archivo utilizando el {$L xxx} directiva.El C archivo es compilado con C++Builder el compilador de línea de comandos.Para satisfacer la C del archivo de biblioteca de tiempo de ejecución de dependencias (_assert, memmove, etc), estoy incluyendo la crtl unidad de Allen Bauer mencionado aquí.

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 puedo compilar la unidad en un proyecto de Delphi (.dproj) todo funciona correctamente.

Si puedo compilar la unidad de C++Builder de proyecto (.cbproj) se produce un error con el error:

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

Y, de hecho, no hay un crtl.obj en el archivo de RAD Studio carpeta de instalación.Hay una .dcu, pero no .pas.Tratando de agregar crtdbg a la cláusula uses (el encabezado de C donde _assert se define) da un error de que no puede encontrar crtdbg.dcu.

Si puedo quitar el utiliza cláusula, en lugar de con errores que __assert y _memmove no se encuentran.

Así, en una unidad en Delphi en C++Builder proyecto, ¿cómo puedo exportar las funciones de la C biblioteca de tiempo de ejecución por lo que están disponibles para el enlace?

Ya soy consciente de Rudy Velthuis del artículo.Me gustaría evitar manualmente escrito en Delphi envolturas si es posible, ya que yo no los necesitan en Delphi y C++Builder ya debe incluir las funciones necesarias.

Editar

Para cualquier persona que quiera jugar en casa, el código está disponible en Abbrevia del repositorio de Subversion en https://tpabbrevia.svn.sourceforge.net/svnroot/tpabbrevia/trunk.Me he tomado David Heffernan y el asesoramiento que se ha añadido una "AbCrtl.pas" de la unidad que imita la tecla ctrl.dcu cuando se compila en C++Builder.Que consiguió el PPMd de trabajo de apoyo, pero la Lzma y WavPack bibliotecas de ambos errores con errores de enlace:

[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, todos ellos se declaran correctamente, y el _beginthreadex que uno es en realidad declarado en AbLzma.pas, por lo que es utilizado por el puro Delphi compilar así.

A ver a ti mismo, sólo tienes que descargar el tronco (o simplemente la "fuente" y "paquetes" directorios), desactivar el {$IFDEF BCB} bloque en la parte inferior de AbDefine.inc, y tratar de compilar el C++Builder "Abbrevia.cbproj" del proyecto.

¿Fue útil?

Solución

Mi opinión sobre esto es que solo necesita la unidad Delphi en la versión Delphi del proyecto.

En la versión de C ++ Builder, simplemente compila y enlace Foolib.c como si fuera un archivo C (¡lo es!) En la versión Delphi del programa crea el .OBJ con BCC32, usa CTRL, etc. como se describe.

¿Por qué quieres concluir una biblioteca C en un envoltorio de Delphi para ser consumido en C ++?

Edición 1

Has agregado aclaraciones en los comentarios.

Otra opción a considerar sería evitar CRTL e implementar las funciones faltantes en Foowrapper. Lo hago de esa manera en lugar de usar CRTL porque eso me da más control y entiendo cómo se llama. Por ejemplo, no quiero ninguna llamada para printf() goteo en mi aplicación GUI o mi dll.

Esta podría ser una opción atractiva si solo le falta un puñado de funciones. A menudo, la forma más ordenada de obtenerlos es vincularlos desde msvcrt.dll, que es un componente del sistema estándar en estos días. Por supuesto, parece un poco pesado vincular en msvcrt.dll solo para llegar a memset(), memcpy() etc.

¿Cuántas funciones faltantes hay cuando compilas la unidad Delphi sin CRTL?

Edición 2

Estoy agregando esto a la respuesta para mostrar algún código. De mi propia base de código, ofrezco esto:

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

Para ftol Enlace en ftol.obj que supongo que extraí de uno de los archivos lib en el compilador BCC55 que uso.

pienso strncmp Debería ser bastante rutinario para implementar en Pascal.

sprintf es más difícil en general, pero puede encontrar que solo se usa para algo trivial como el entero para la cadena. En cuyo caso, podría falsificar el código C para llamar a una rutina dedicada a eso e implementarla de manera trivial.

Para ser honesto contigo, creo que 'msvcrt.dll' se ve bastante atractivo.

Edición 3

¿Hablé pronto? Puedes tirar de un perfectamente útil sprintf Fuera del usuario32.dll que casi todos los procesos se han cargado de todos modos. Asegúrate de elegir wsprintfA Si es una versión ANSI que necesitas.

Edición 4

me doy cuenta _beginthreadex. Dices que esto se define en una unidad Delphi diferente. Para que el compilador lo vea, debe redeclarlo en abctrl.pas y desde allí llame a la versión real en ablzma.pas.

Cuando incluye un .obj en un archivo Delphi .pas, el compilador debe poder resolver todas las referencias en el archivo .obj desde la unidad Delphi que se vincula a .OBJ. Todo este juego es tratado por el compilador en lugar del enlazador.

A veces se enreda en nudos con el orden en que incluye los archivos .obj y la solución es usar declaraciones de avance, pero esa es otra historia.

Otros consejos

En este caso, se supone que las funciones que le interesan están disponibles directamente desde el C RTL, por lo que fingir el enlazador con un archivo obj ficticio (vacío) debería funcionar, ya que satisfará el enlazador que busca el archivo OBJ que Delphi le dijo Necesitas, pero aún encuentro las funciones en el RTL.

Tarde, pero más completo: CRTL.DCU funciona sin problemas desde D2005 hasta XE2.

Para D6 y D7 hay una dependencia de Midaslib.dcu. Bueno, en realidad no, la DCU se distribuye con una cláusula de usos sucios.

Para D6 y D7, debe crear un sustituto de midas vacío.pas, como:

unit midaslib;
interface
implementation
end.

¡Ahora puede usar CRTL.DCU sin los errores internos!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top