Menú
Gratis
Registro
hogar  /  Multimedia/ Bibliotecas dinámicas dll ejemplos delphi. Crear una DLL

Ejemplos de bibliotecas dinámicas dll delphi. Crear una DLL

DLL- Biblioteca de enlaces dinámicos, de lo contrario, una biblioteca de enlaces dinámicos que le permite reutilizar las mismas funciones en diferentes programas. En realidad, es una herramienta bastante útil, especialmente porque una vez escrita, una biblioteca se puede usar en muchos programas. En la lección de hoy aprenderemos a trabajar con dll¡Y por supuesto crearlos!
Bueno, ¡comencemos!

¡Comencemos por crear nuestra primera biblioteca de vínculos dinámicos! Vamos a Delfos e inmediatamente suba al menú Archivo -> Nuevo -> Otro.
La siguiente ventana aparece ante nosotros:

Seleccione Biblioteca de vínculos dinámicos de la lista (en versiones anteriores a 2009 Delfos elemento se llama Asistente para DLL).

Como resultado, solo tenemos una ventana con el código, ¡observe que no tenemos ningún formulario aquí!
Ahora comienza la diversión. Escribamos nuestros primeros procedimientos en la biblioteca.

biblioteca Proyecto2;
//Probablemente ya te hayas dado cuenta de que en lugar de program
//al crear una dll se usa la palabra biblioteca.
// Biblioteca de significantes.
usos
Sysutils, cuadros de diálogo,
clases; // ¡Atención! No olvides incluir estos módulos,
// de lo contrario el código no funcionará

($R*.res)
(ESTA PARTE PONDRÁ EL CÓDIGO DLL)

Primera llamada de procedimiento; llamada estándar; exportar;
//Stdcall: esta declaración empuja los parámetros a la pila
// de derecha a izquierda y alineado a valor estandar
//La exportación, en principio, puede omitirse, usarse para aclaración
//exportar procedimiento o función.

Comenzar
Mostrar mensaje(" Mi primer procedimiento en dll");

fin;

LlamadaProcedimientoDoble; llamada estándar; exportar;
Comenzar
Mostrar mensaje(" mi segundo procedimiento");
//Llama el mensaje a la pantalla
fin;

Exporta FirstCall, DoubleCall;
//Exportaciones contiene una lista de elementos exportados.
//Que luego será importado por algún programa.

comenzar
fin.

Aquí es donde nos detendremos por ahora. Para un ejemplo sencillo esto será suficiente. Ahora guardamos nuestro proyecto, yo personalmente lo guardé con el nombre Project2.dll y presione la combinación de teclas CTRL + F9 para compilar la biblioteca. En la carpeta donde guardaste el archivo dpr, debe aparecer un archivo con la extensión dll, esta es nuestra biblioteca recién creada. Lo tengo llamado Project2.dll

Abordemos ahora los procedimientos de llamada desde esta biblioteca. Creamos una nueva aplicación de acuerdo con el esquema estándar. Ante nosotros no hay nada inusual, solo una forma. Guardamos la nueva aplicación en alguna carpeta. Y en la misma carpeta copiamos el recién creado biblioteca dll. Aquellos. en este ejemplo Project2.dll

Ahora debe elegir cómo llamar a las funciones de la biblioteca. Hay dos métodos de llamada en total.

Método número 1
Quizás este sea el método más simple para llamar a procedimientos en la biblioteca.
Ideal para trabajar con una sola biblioteca.

Aquí vamos...
Después de la palabra clave de implementación, escriba el siguiente código:

Primera llamada de procedimiento; llamada estándar; externo "Proyecto2.dll";
// Project2.dll puede ser cualquier nombre de biblioteca en su lugar

LlamadaProcedimientoDoble; llamada estándar; externo "Proyecto2.dll";

Aquí, como habrás adivinado, le decimos al programa los nombres de nuestros procedimientos y decimos que están en biblioteca dll, en mi caso llamado Project2.dll

Ahora, para llamar a estos procedimientos, solo necesitamos insertar sus nombres en cualquier parte del código, lo cual haremos ahora. Lanzamos 2 componentes de botón en el formulario desde la pestaña Estándar y creamos un controlador de eventos OnClick en cada uno

Al hacer clic en el primer botón:


Comenzar
primera llamada;
fin;

Al hacer clic en el segundo botón:


Comenzar
llamada doble; // El nombre del procedimiento que esta en la dll
fin;

¡Eso es todo!

Método número 2:
Más complicado que el primero, pero tiene sus ventajas, y lo más importante, es ideal para plugins.
Para aplicación este método, en primer lugar declaramos varias variables globales:

Var
LibHandle: MóduloH; //Enlace al módulo de la biblioteca
FirstCall: procedimiento; llamada estándar;
//Nombres de nuestros procedimientos en la biblioteca.

DoubleCall: procedimiento; llamada estándar;

Luego, después de la palabra clave de implementación, escribimos un procedimiento que cargará nuestra biblioteca:

Cargar ProcedimientoMiLibrería(NombreArchivo: Cadena);
Comenzar
LibHandle:= LoadLibrary(PWideChar(FileName));
//¡Cargar la biblioteca!
// ¡Atención! PChar para versiones anteriores a 2009 Delphi
Si LibHandle = 0 entonces comience
cuadro de mensaje(0,"",0,0);
salida;
fin;
PrimeraLlamada:= ObtenerDirecciónProc(LibHandle,"PrimeraLlamada");
//Obtener un puntero a un objeto
//Enlace del primer parámetro al módulo de la biblioteca
// Nombre del objeto del segundo parámetro en dll

DoubleCall:= GetProcAddress(LibHandle,"DoubleCall ");
Si @FirstCall = nil entonces comience

Cuadro de mensaje(0," No se puede cargar la biblioteca",0,0);
salida;
fin;
Si @DoubleCall = nil entonces comience
//Comprobar la presencia de esta función en la biblioteca.
Cuadro de mensaje(0," No se puede cargar la biblioteca",0,0);
salida;
fin; fin;

Después de eso, en el formulario, creamos un controlador de eventos OnCreate, en el que, utilizando el procedimiento recién creado, cargaremos nuestro biblioteca

Procedimiento TForm1.FormCreate(Remitente: TObject);
Comenzar
LoadMyLibrary("Proyecto2.dll");
fin;

Ahora, nuevamente, para llamar a los procedimientos necesarios desde nuestra biblioteca, solo necesitamos insertar sus nombres en cualquier parte del código. Para hacer esto, lanzamos 2 componentes Button en el formulario desde la pestaña Estándar y creamos un controlador de eventos OnClick en cada uno.

Al hacer clic en el primer botón:

Procedimiento TForm1.Button1Click(Remitente: TObject);
Comenzar
primera llamada; // El nombre del procedimiento que esta en la dll
fin;

Al hacer clic en el segundo botón:

Procedimiento TForm1.Button2Click(Sender: TObject);
Comenzar
llamada doble; // El nombre del procedimiento que esta en la dll
fin;

Y finalmente, creamos un controlador de eventos OnDestroy en el formulario en el que descargamos biblioteca dll de memoria

Procedimiento TForm1.FormDestroy(Remitente: TObject);
Comenzar
LibreLibrería(LibHandle);
//Descargar la biblioteca de la memoria.
fin;

¡Eso es todo! El segundo método resultó bastante engorroso, pero tiene la ventaja de refinar el objeto almacenado en la biblioteca.

PD ¿Quiere adelantarse a todos los demás visitantes del sitio con los últimos tutoriales en vídeo, podcasts de audio y artículos sobre Delphi?
¿Participar en concursos y unirte poco a poco a nuestro equipo?
Entonces, suscríbase ahora mismo al boletín multimedia gratuito del sitio.
¡Ya somos más de 3500 personas!

Una DLL le permite combinar código reutilizable en un todo. Las funciones de las DLL se pueden vincular dinámicamente en tiempo de ejecución, a diferencia de las funciones de los paquetes de Delphi que se vinculan estáticamente en la etapa de compilación de la aplicación.

Para crear una biblioteca DLL, primero debe ejecutar el comando de menú Archivo|Nuevo|Otro y seleccionar el elemento Asistente de DLL en la página Nuevo del cuadro de diálogo Nuevo elemento.

El asistente de DLL creará automáticamente plantilla en blanco para la DLL. A diferencia de un módulo normal que comienza con la palabra clave unit, un módulo DLL comienza con la palabra clave library. La sección de usos de un módulo DLL requiere que solo se incluyan dos paquetes: SysUtils y Classes.

La creación de una función DLL consta de varios pasos:

1. Primero, en la sección de implementación del módulo, ingrese la firma de la función y programe el código que ejecuta la función.

3. Finalmente, una función que se supone que debe usarse no solo dentro del módulo, sino también llamada desde otras aplicaciones, debe declararse como exportable en la sección de exportaciones.

Las funciones de una DLL se pueden llamar tanto desde aplicaciones desarrolladas en Delphi como desde aplicaciones escritas en otros lenguajes de programación como C++.

El orden de asignación de memoria para parámetros y liberación es diferente para diferentes lenguajes de programación. Para evitar un error en tiempo de ejecución, la declaración de una función en una DLL y su declaración en una aplicación deben utilizar el mismo mecanismo de paso de parámetros. Al declarar un procedimiento o función, se puede especificar uno de los siguientes mecanismos de paso de parámetros:

El método de paso de parámetros se especifica mediante un punto y coma después de la descripción de la función. Por ejemplo:

función F1(X, Y, Z: Real]: Real; stdcall;.

Varias maneras los pases de parámetros determinan el orden en que se pasan los parámetros (de izquierda a derecha o de derecha a izquierda) y también indican quién desasignará la memoria de la pila (el procedimiento llamado o el procedimiento de llamada). Cuando use archivos DLL como componentes llamados desde aplicaciones en otros lenguajes de programación, use el modificador de llamada adecuado. Para aplicaciones C++, se usa el modificador de llamada stdcall.

Para que una función descrita en una DLL pueda llamarse desde otra aplicación, la función debe exportarse. La lista de todas las funciones exportadas se indica en la sección de exportaciones separadas por comas

y termina con un punto y coma. Las funciones se pueden exportar de tres maneras:

Por el nombre de la función utilizada en la DLL;

Por nombre de función, dado como nombre de exportación;

Por el índice asignado a la función.

Para asignar algún índice a una función, debe especificarse en la sección de exportaciones después del nombre de la función con palabra claveíndice.

Para que la función exportada sea llamada por un nombre diferente al nombre utilizado en la DLL, en la sección de exportaciones, después del nombre de la función, debe especificar la palabra clave del nombre y el nuevo nombre de exportación para esta función.

DLL: la biblioteca no es un módulo ejecutable. Para obtener su código, basta con compilar el proyecto.

proyecto de biblioteca;

SysUtils, Clases;

función F1(X, Y: Entero): Entero; llamada estándar;

Vinculación estática de una DLL

Una DLL se puede vincular estática o dinámicamente. Cuando se incluye una DLL, se carga en la memoria de la aplicación.

Con un enlace estático, la DLL se carga una vez cuando se inicia la aplicación. A lo largo de la ejecución de la aplicación, el nombre de una función importada de una DLL vinculada estáticamente apunta a la misma función (punto de entrada de la DLL) en la misma DLL. Todas las funciones de la DLL que se utilizarán en la aplicación inicialmente deben declararse como externas. En este caso, debe especificar, si es necesario, un modificador de llamada. Si se llama a una función por índice, entonces se le debe dar el nombre utilizado en la aplicación y el índice de la función en la DLL.

Las declaraciones de funciones externas se realizan en la sección de implementación antes de que se utilicen estas funciones.

Anuncio externo funciones con la palabra clave externa especifica que se usarán enlaces estáticos.

TForm = clase (TForm)

Editl: TEdit; [Campo para ingresar el primer valor)

Edit2: TEdit; (Campo para ingresar el segundo valor)

Edit3: TEdit; (Campo para mostrar el resultado

ejecutando una función desde una DLL)

Botón: TButton; (Llamar a una función utilizada por su nombre)

Botón2: BotónT; [Llamar a una función utilizada por index)

procedimiento ButtonlClickfSender: TObject);

procedimiento Button2Click(Remitente: TObject);

(Declaraciones privadas)

(Declaraciones públicas)

(Declaración de funciones exportadas)

función Fl (i: Entero; j: Entero): Entero; llamada estándar;

externo "proyectol.dll";

función F2 (i: Entero; j: Entero): Entero; llamada estándar;

externo "Projectl.dll índice 2;

procedimiento TForml.ButtonlClick(Remitente: TObject);

(Llamar a una función exportada)

Edit3.Text:=IntToStr(Fl(StrToInt(Editl.Text),StrToInt(Edit2.Text) ));

procedimiento TForml.Button2Click(Remitente: TObject);

Edit3.Text:=JntToStr(F2(StrToInt(Editl.Text),StrToInt(Edit2.Text)));

Vinculación dinámica de una DLL

A diferencia de un vínculo estático para una DLL, que ocurre cuando se carga una aplicación, un vínculo dinámico para una DLL se puede realizar en cualquier punto de la ejecución de un programa. Una vez que se ha llamado a una función desde una DLL, se puede desactivar. Con el uso simultáneo de varias bibliotecas DLL, esto genera un ahorro significativo en la memoria. Para vincular dinámicamente una DLL, use las funciones de la API de Windows. API de Windows - este es un conjunto características estándar Se utiliza para implementar la interacción con el sistema operativo.

Al llamar a una función desde una DLL de enlace dinámico, en lugar de definir el nombre de la función como externo en el caso de un enlace estático, debe definir un nuevo tipo que coincida con el tipo de función que se llama y crear una variable de ese tipo.

Para llamar a una función desde una DLL de enlace dinámico, haga lo siguiente:

1. Cree un nuevo tipo. correspondiente al tipo de la función llamada (el nombre del nuevo tipo se puede ingresar después de la sección de tipo).

Por ejemplo:

TMyFl=función(i,j:Entero):Entero; llamada estándar;

2. En la sección var de la sección de interfaz del módulo, cree una variable del tipo de función creada. Por ejemplo: MyFl: TMyFl;

3. Antes de cargar la DLL, declare una variable Integer que contendrá el descriptor de la biblioteca incluida.

4. Llame al método LoadLibrary, que carga la DLL. Por ejemplo; h:=LoadLibrary("Proyectol.dll");

5. Verifique si la conexión de la biblioteca fue exitosa. Si el nombre de la DLL es incorrecto o no se encuentra la DLL, la función LoadLibrary devolverá 0.

6. En caso de una conexión exitosa de la biblioteca DLL, debe obtener la dirección de la función. Para ello se utiliza función de ventanas API GetProcAddress, que especifica el descriptor de la biblioteca DLL y el nombre de la función del complemento como parámetros. Por ejemplo: @MyFl: =GetProcAddress(h, " Fl ");

7. Si se obtiene la dirección de la función, entonces el valor de la dirección (en nuestro ejemplo @MyFl) no debe ser igual a cero.

8. En este momento, puede llamar a la función desde la DLL vinculada dinámicamente.

9. Para liberar y descargar la DLL, llame al método FreeLibrary, que desvincula la DLL.

Windows, Mensajes, SysUtils, Variantes, Clases, Gráficos,

Controles, Formularios, Diálogos, StdCtrls;

TForm = clase (TForm)

Botón 3: Botón T;

procedimiento Botón3Clic

procedimiento TForml.Button3Click(Remitente: TObject);

h:=LoadLibrary("Proyectol.dll");

si h<>0 entonces

@MyFl:=GetProcAddress(h,"Fl");

si @MiFl<>cero entonces

Edit3.Text:=IntToStr(MyFl(StrToInt(Editl.Text),

StrToInt(Edit2.Text)));

Uso de una DLL para invocar cuadros de diálogo modales comunes.

El resultado de ejecutar un procedimiento desde una biblioteca DLL puede ser la visualización de algún cuadro de diálogo modal. Para hacer esto, cree un objeto de formulario en el método exportado, muéstrelo como un cuadro de diálogo modal y luego elimine el objeto de formulario. En este caso, el propio formulario debería proporcionar una llamada al método Close para finalizar el diálogo.

Para crear un formulario, se utiliza el método Create, pasando como parámetro un puntero al formulario principal, el formulario de la aplicación que realiza la llamada. Este parámetro se pasa a la función DLL llamada.

proyecto de biblioteca;

Unitl_DLL en "Unitl_DLL.pas" (Forml);

procedimiento MyModalForm (var Z:Integer ;F:TForm1); llamada estándar;

Formulario1:=TForml.Create(F);

(El parámetro F se pasa cuando se llama al procedimiento y contiene un puntero

al formulario principal - el formulario de la aplicación de llamada)

Debido al rápido desarrollo de las tecnologías de programación, cada vez más personas se enfrentan al problema de aumentar las capacidades de sus programas. Este artículo está dedicado a este tema, a saber, la programación de DLL en Borland Delphi. Además, dado que abordaremos los problemas del uso de DLL, también abordaremos la importación de funciones desde las DLL de otras personas (incluidas las del sistema, es decir, WinAPI).

Aplicaciones DLL

Entonces, ¿por qué se necesitan las DLL y dónde se usan? Estas son solo algunas de sus áreas de aplicación:

  • Bibliotecas separadas que contiene útil para los programadores funciones adicionales. Por ejemplo, funciones para trabajar con cadenas o bibliotecas complejas para convertir imágenes.
  • Tiendas de recursos. En una DLL, puede almacenar no solo programas y funciones, sino también todo tipo de recursos: íconos, imágenes, matrices de cadenas, menús, etc.
  • Bibliotecas de apoyo. Un ejemplo son las bibliotecas de paquetes tan conocidos como: DirectX, ICQAPI(API para ICQ), OpenGL etc.
  • partes del programa. Por ejemplo, una DLL puede almacenar ventanas de programas (formularios), etc.
  • Complementos(Complementos). - ¡Ahí es donde está el alcance real de los pensamientos del programador! Los complementos son adiciones al programa que amplían sus capacidades. Por ejemplo, en este artículo veremos la teoría de crear un complemento para su propio programa.
  • recurso compartido. DLL( Biblioteca de enlaces dinámicos) puede ser utilizado por varios programas o procesos a la vez (los llamados. intercambio- recurso compartido)

Breve descripción de funciones y trucos para trabajar con DLL

Entonces, ¿qué trucos y funciones necesitas usar para trabajar con una DLL? Analicemos dos métodos para importar funciones de la biblioteca:

1 camino. Vincular una DLL a un programa. Este es el método más simple y fácil para usar funciones importadas desde una DLL. Sin embargo (y debe prestar atención a esto) este método tiene un inconveniente muy importante: si no se encuentra la biblioteca que usa el programa, entonces el programa simplemente no se iniciará, dará un error e informará que no se encontró el recurso DLL. Y se buscará en la biblioteca: en el directorio actual, en el directorio del programa, en el directorio WINDOWS\SYSTEM, etc.
Entonces, para empezar, la forma general de esta técnica:

implementación
...
función FunctionName(Par1: Par1Type; Par2: Par2Type; ...): ReturnType; llamada estándar; externo"NOMBREDLL.DLL" nombre"Nombre de la función" índiceÍndiceFunción;
// o (si no es una función, sino un procedimiento):
procedimiento NombreProcedimiento(Par1: Par1Tipo; Par2: Par2Tipo; ...); llamada estándar; externo"NOMBREDLL.DLL" nombre"nombreprocedimiento" índiceÍndiceProc;

Aquí: Nombre de la función(o ProcedimientoNombre) - el nombre de la función (o procedimiento) que se utilizará en su programa;
Par1, Par2, ...- nombres de parámetros de función o procedimiento;
Tipo Par1, Tipo Par2, ...- tipos de parámetros de una función o procedimiento (por ejemplo, Entero);
tipo de devolución- tipo de valor devuelto (solo para una función);
llamada estándar- una directiva que debe coincidir exactamente con la utilizada en la propia DLL;
externo "NOMBREDLL.DLL"- directiva que especifica el nombre de la DLL externa desde la que se importará función dada o procedimiento (en este caso - NOMBREDLL.DLL);
nombre "NombreFunción" ("NombreProcedimiento")- una directiva que especifica el nombre exacto de una función en la propia DLL. Esta es una directiva opcional que le permite usar una función en el programa que tiene un nombre diferente al verdadero (que tiene en la biblioteca);
índice Índice de función (Índice de procedimiento)- una directiva que especifica el número ordinal de una función o procedimiento en una DLL. Esta es también una directiva opcional.

2 vías. Carga dinámica de DLL. Este es un método mucho más complejo pero también más elegante. Carece de la desventaja del primer método. Lo único que es desagradable es la cantidad de código requerido para implementar esta técnica, y la dificultad es que la función importada desde la DLL está disponible solo cuando esta DLL está cargada y está en la memoria... A continuación se puede encontrar un ejemplo, pero por ahora - Breve descripción Funciones WinAPI utilizadas por este método:

Cargar biblioteca(nombre de archivo lib: PCchar) - cargando la biblioteca especificada LibFileName en la memoria. En caso de éxito, la función devuelve un identificador ( Mango) DLL en memoria.
ObtenerDirecciónProc(Módulo: Mango; NombreProc: PCchar) - lee la dirección de la función de biblioteca exportada. En caso de éxito, la función devuelve un identificador ( TFarProc) funciona en la DLL cargada.
biblioteca libre(MóduloLib: Mango) - invalida el LibModule y libera la memoria asociada a él. Cabe señalar que después de llamar a este procedimiento, las funciones de esta biblioteca ya no están disponibles.

Practica y ejemplos

Bueno, ahora es el momento de dar un par de ejemplos del uso de los métodos y técnicas anteriores:

Ahora lo mismo, pero de la segunda manera, con carga dinámica:

(... Aquí viene el encabezado del archivo y la definición del formulario TForm1 y su instancia Form1)

variable
Formulario1: TForm1;
ObtenerTextoSimple: función(LangRus: booleano): PChar;
LibHandle: THandle;

procedimiento Button1Click(Remitente: TObject);
comenzar
("Limpiamos" la dirección de la función de "suciedad")
@GetSimpleText:= nil;
(Intentando cargar la biblioteca)
LibHandle:= LoadLibrary("MYDLL.DLL");
(Si todo esta bien)
si LibHandle >= 32 entonces comience
(... entonces estamos tratando de obtener la dirección de la función en la biblioteca)
@GetSimpleText:= GetProcAddress(LibHandle,"GetSimpleText");
(Si todo está bien aquí)
si @GetSimpleText<>cero entonces
(... luego llamamos a esta función y mostramos el resultado)
Mostrar Mensaje(StrPas(GetSimpleText(True)));
fin;
(Y no olvides liberar memoria y descargar la DLL)
LibreLibrería(LibHandle);
fin;

NOTA : Debe abstenerse de usar el tipo de cadena en las funciones de biblioteca, porque hay problemas con el "compartir memoria" al usarlo. Puede leer más sobre esto (aunque en inglés) en el texto del proyecto DLL vacío que crea Delphi (Archivo -> Nuevo -> DLL). Por lo tanto, es mejor usar PChar y luego convertirlo en una cadena con StrPas si es necesario.

Bueno, ahora analicemos la DLL en sí directamente:

Ubicación en recursos y formularios DLL

En una DLL, puede colocar no solo funciones, sino también cursores, imágenes, íconos, menús, líneas de texto. No nos detendremos en esto. Solo notaré que para cargar el recurso, debe cargar la DLL y luego, una vez recibido su descriptor, cargar el recurso con la función adecuada (LoadIcon, LoadCursor, etc.). En esta sección, solo abordaremos brevemente la ubicación de las ventanas de la aplicación (es decir, los formularios en Delphi) en las DLL.

Para hacer esto, debe crear una nueva DLL y agregarla nueva forma(Archivo -> Nuevo -> DLL y luego Archivo -> Nuevo formulario). Además, si el formulario es un cuadro de diálogo ( forma modal(bsDialog)), luego agregamos la siguiente función a la DLL (digamos que el formulario se llama Form1, y su clase es TForm1):

Si necesita colocar un formulario no modal en la DLL, debe realizar dos funciones: abrir y cerrar el formulario. En este caso, debe obligar a la DLL a recordar el identificador de este formulario.

Crear complementos

Aquí no consideraremos los complementos en detalle, porque. los ejemplos ya dados anteriormente lo ayudarán a comprender fácilmente la mayor parte de la programación DLL. Permítanme recordarles que el complemento es una adición al programa que amplía sus capacidades. Al mismo tiempo, el programa en sí debe prever necesariamente la presencia de tales adiciones y permitirles cumplir su propósito.

Es decir, por ejemplo, para crear un complemento para editor de gráficos, que realizaría la transformación de la imagen, debe proporcionar al menos dos funciones en el complemento (y, en consecuencia, llamar a estas funciones en el programa), una función que devolvería el nombre del complemento (y/o su tipo) para agregar este complemento para el menú (o en la barra de herramientas), además la función principal es transmitir y recibir una imagen. Aquellos. primero, el programa busca complementos, luego, para cada uno encontrado, llama a su función de identificación con un nombre estrictamente definido (por ejemplo, GetPluginName) y agrega el elemento deseado al menú, luego, si el usuario ha seleccionado este elemento, llama la segunda función, que pasa la imagen de entrada (o nombre de archivo, que contiene esta imagen), y esta función, a su vez, procesa la imagen y la devuelve en una nueva forma (o un nombre de archivo con una nueva imagen). Ese es el objetivo del plugin... :-)

Epílogo

Este artículo muestra los aspectos principales del uso y la creación de archivos DLL en Borland Delphi. Si tiene alguna pregunta, envíemela por correo electrónico: [correo electrónico protegido], y aún mejor: escriba en la conferencia de este sitio para que otros usuarios puedan ver su pregunta e intentar responderla.

Karikh Nikolay. Región de Moscú, Zhukovsky

Abreviatura DLL significa "biblioteca vinculada dinámicamente". DLL en Delfos Este es un archivo que contiene los procedimientos y funciones necesarios para la operación de un programa de computadora, con el cual el programa está conectado en la etapa de ejecución.

Parecería que todas las subrutinas necesarias se pueden describir en el cuerpo del programa, ¿por qué necesita crear una adicional? archivo dll y conectarse a él en tiempo de ejecución? Esto se hace para una mayor flexibilidad. programa creado. De hecho, con el tiempo, algunos algoritmos de procesamiento de datos pueden cambiar. Si los procedimientos de procesamiento estarán contenidos en el cuerpo del programa, deberá volver a compilarse y transferirse nuevamente a los clientes con un archivo bastante grande. Transferir un pequeño archivo dll que contiene solo unos pocos procedimientos es mucho más fácil e incluso automático.

Además, trabajo dlls completamente independiente del lenguaje de programación en el que se creará. Por tanto, podemos encomendar la creación de una dll para nuestro programa a terceros desarrolladores, sin pensar en los lenguajes de programación que hablan. Todo esto, por supuesto, acelera enormemente la creación y transferencia del proyecto terminado a los clientes.

Crear una DLL

Creando una dll en Delphi no más difícil de crear módulo adicional. Ejecute el comando Archivo -> Nuevo -> -> Otro... En el cuadro de diálogo que aparece, seleccione el icono DLL Wisard. Como resultado, Delphi creará un proyecto DLL de código auxiliar:

biblioteca Proyecto 1;

(Nota importante sobre la gestión de la memoria DLL: ShareMem debe ser el
primera unidad en la cláusula USES de su biblioteca Y la de su proyecto (seleccione
Project-View Source) cláusula USES si su DLL exporta cualquier procedimiento o
funciones que pasan cadenas como parámetros o resultados de funciones. Este
se aplica a todas las cadenas pasadas hacia y desde su DLL, incluso aquellas que
están anidados en registros y clases. ShareMem es la unidad de interfaz para
el administrador de memoria compartida BORLNDMM.DLL, que debe implementarse junto
con tu DLL. Para evitar el uso de BORLNDMM.DLL, pase la información de la cadena
utilizando parámetros PChar o ShortString. )

usos
utilidades del sistema,
clases;

($R*.res)

comenzar
fin
.

Elija un nombre para el nuevo dll y guárdelo en una carpeta separada ejecutando el comando archivo -> Guardar como... Aparecerán 4 archivos en la carpeta, entre los cuales no habrá ningún archivo dll real. Naturalmente, es solo archivos de texto, que contiene una descripción del proyecto. Para crear el archivo dll final, debe compilar el proyecto. Ejecutar el comando proyecto -> Compilar proyecto. Como resultado, nuestra carpeta en realidad contendrá archivo dll, con el que se conectará el programa principal.

Hasta ahora, esta es una biblioteca vacía.

...el texto está siendo editado actualmente...



Introducción

Debido al rápido desarrollo de las tecnologías de programación, cada vez más personas se enfrentan al problema de aumentar las capacidades de sus programas. Este artículo está dedicado a este tema, a saber, la programación de DLL en Borland Delphi. Además, dado que abordaremos los problemas del uso de DLL, también abordaremos la importación de funciones desde las DLL de otras personas (incluidas las del sistema, es decir, WinAPI).

Aplicaciones DLL

Entonces, ¿por qué se necesitan las DLL y dónde se usan? Estas son solo algunas de sus áreas de aplicación:

Bibliotecas separadas Contiene funciones adicionales útiles para los programadores. Por ejemplo, funciones para trabajar con cadenas o bibliotecas complejas para convertir imágenes. Almacenes de recursos Una DLL puede almacenar no solo programas y funciones, sino también todo tipo de recursos: íconos, imágenes, arreglos de cadenas, menús, etc. Bibliotecas de soporte Los ejemplos incluyen bibliotecas de paquetes tan conocidos como: DirectX, ICQAPI (API para ICQ), OpenGL, etc. Partes de un programa Por ejemplo, una DLL puede almacenar ventanas de programas (formularios), etc. Complementos (Plugins) ¡Ahí es donde está el verdadero espacio para los pensamientos del programador! Los complementos son adiciones al programa que amplían sus capacidades. Por ejemplo, en este artículo veremos la teoría de crear un complemento para su propio programa. Una DLL de recursos compartidos (Biblioteca de enlaces dinámicos) puede ser utilizada por varios programas o procesos a la vez (el llamado recurso compartido es un recurso compartido)

Breve descripción de funciones y trucos para trabajar con DLL

Entonces, ¿qué trucos y funciones necesitas usar para trabajar con una DLL? Analicemos dos métodos para importar funciones de la biblioteca:

1 manera Vincular una DLL a un programa.

Este es el método más simple y fácil para usar funciones importadas desde una DLL. Sin embargo (y debe prestar atención a esto) este método tiene un inconveniente muy importante: si no se encuentra la biblioteca que usa el programa, entonces el programa simplemente no se iniciará, dará un error e informará que no se encontró el recurso DLL. Y se buscará en la biblioteca: en el directorio actual, en el directorio del programa, en el directorio WINDOWS\SYSTEM, etc. Entonces, para empezar, la forma general de esta técnica:


FunctionName (o ProcedureName) el nombre de la función (o procedimiento) que se usará en su programa; Par1, Par2, ... nombres de parámetros de función o procedimiento; Par1Type, Par2Type, ... tipos de parámetros de función o procedimiento (por ejemplo, Integer); ReturnType tipo de retorno (función solamente); directiva stdcall, que debe coincidir exactamente con la utilizada en la propia DLL; directiva externa "DLLNAME.DLL" que especifica el nombre de la DLL externa desde la cual se importará la función o procedimiento dado (en este caso, DLLNAME.DLL); name "FunctionName" ("ProcedureName") directiva que especifica el nombre exacto de una función en la propia DLL. Esta es una directiva opcional que le permite usar una función en el programa que tiene un nombre diferente al verdadero (que tiene en la biblioteca); index FunctionIndex (ProcedureIndex) Una directiva que especifica el número ordinal de una función o procedimiento en una DLL. Esta es también una directiva opcional.

Este es un método mucho más complejo pero también más elegante. Carece de la desventaja del primer método. Lo único desagradable es la cantidad de código que se requiere para implementar esta técnica, y la dificultad es que la función importada desde la DLL está disponible solo cuando esta DLL está cargada y en memoria... Puedes leer el ejemplo a continuación, pero por ahora, una breve descripción de las funciones WinAPI utilizadas por este método:

LoadLibrary(LibFileName: PChar) Carga la biblioteca especificada LibFileName en la memoria. En caso de éxito, la función devuelve un identificador (THandle) a la DLL en la memoria. GetProcAddress(Module: THandle; ProcName: PChar) obtiene la dirección de una función de biblioteca exportada. En caso de éxito, la función devuelve un identificador (TFarProc) a la función en la DLL cargada. FreeLibrary(LibModule: THandle) invalida el LibModule y libera la memoria asociada a él. Cabe señalar que después de llamar a este procedimiento, las funciones de esta biblioteca ya no están disponibles.

Practica y ejemplos

Bueno, ahora es el momento de dar un par de ejemplos del uso de los métodos y técnicas anteriores:

Ejemplo 1: vincular una DLL a un programa


Ahora lo mismo, pero de la segunda manera, con carga dinámica:


Nota:

Debe abstenerse de usar el tipo de cadena en las funciones de biblioteca, porque hay problemas con el "compartir memoria" al usarlo. Puede leer más sobre esto (aunque en inglés) en el texto del proyecto DLL vacío que crea Delphi (Archivo -> Nuevo -> DLL). Por lo tanto, es mejor usar PChar y luego convertirlo en una cadena con StrPas si es necesario.

Bueno, ahora analicemos la DLL en sí directamente:

Ejemplo 3. Fuente del proyecto MYDLL.DPR


Ubicación en recursos y formularios DLL

En una DLL, puede colocar no solo funciones, sino también cursores, imágenes, íconos, menús, líneas de texto. No nos detendremos en esto. Solo notaré que para cargar el recurso, debe cargar la DLL y luego, una vez recibido su descriptor, cargar el recurso con la función adecuada (LoadIcon, LoadCursor, etc.). En esta sección, solo abordaremos brevemente la ubicación de las ventanas de la aplicación (es decir, los formularios en Delphi) en las DLL.

Para hacer esto, debe crear una nueva DLL y agregarle un nuevo formulario (Archivo -> Nuevo -> DLL, y luego Archivo -> Nuevo formulario). Además, si el formulario es un cuadro de diálogo (formulario modal (bsDialog)), agregue la siguiente función a la DLL (por ejemplo, el formulario se llama Form1 y su clase es TForm1):

Ejemplo 4 Colocación de un formulario en una DLL


Si necesita colocar un formulario no modal en la DLL, debe realizar dos funciones: abrir y cerrar el formulario. En este caso, debe obligar a la DLL a recordar el identificador de este formulario.

Crear complementos

Aquí no consideraremos los complementos en detalle, porque. los ejemplos ya dados anteriormente lo ayudarán a comprender fácilmente la mayor parte de la programación DLL. Permítanme recordarles que el complemento es una adición al programa que amplía sus capacidades. Al mismo tiempo, el programa en sí debe prever necesariamente la presencia de tales adiciones y permitirles cumplir su propósito.

Es decir, por ejemplo, para crear un complemento para un editor de gráficos que realice la conversión de imágenes, debe proporcionar al menos dos funciones en el complemento (y, en consecuencia, llamar a estas funciones en el programa): una función que devolvería el nombre del complemento (y/o su tipo) para agregar este complemento al menú (o barra de herramientas), además la función principal es enviar y recibir una imagen. Aquellos. primero, el programa busca complementos, luego, para cada uno encontrado, llama a su función de identificación con un nombre estrictamente definido (por ejemplo, GetPluginName) y agrega el elemento deseado al menú, luego, si el usuario ha seleccionado este elemento, llama la segunda función, que pasa la imagen de entrada (o nombre de archivo, que contiene esta imagen), y esta función, a su vez, procesa la imagen y la devuelve en una nueva forma (o un nombre de archivo con una nueva imagen). Ese es el objetivo del plugin... :-)

Epílogo

Este artículo muestra los aspectos principales del uso y la creación de archivos DLL en Borland Delphi. Si tiene alguna pregunta, envíemela por correo electrónico: