Historial de actualizaciones: No.1
Hora de actualización: 2001-11-01 20:09
Actualizado por: Musicwind®
Nota de actualización: primer borrador completado.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ ~~~~~~~~~~~~~~~~~~~~~~
resumen:
Este artículo analiza cómo exportar clases en una DLL: muchas subclases basadas en una clase abstracta específica. Esta tecnología utiliza la idea del polimorfismo, lo que nos permite obtener efectos similares a los complementos.
Lectores previstos:
Comprender el concepto de polimorfismo; comprender el concepto de metaclase.
Dificultad técnica:
6/10 .
Para exportar una clase desde una Dll lo primero que debes pensar es en utilizar el paquete bpl. Una desventaja de este método es que el usuario debe saber qué clases están contenidas en el paquete, lo que significa que debe conocer el nombre de la clase; esto es una limitación en cierto sentido. Imagine una situación en la que el usuario define una capa inferior. clase abstracta, y luego muchas clases de aplicación (concretas clase), entonces, para el usuario, espera poder usar estas clases sin conocer las clases específicas; parece un poco misterioso decir esto, pero la situación real es cierta, porque no se puede predecir al definir clases abstractas Cómo ¿Cuántas clases específicas habrá en el futuro? Entonces, ¿qué tipo de tecnología se necesitará para satisfacer tal demanda?
De hecho, la dificultad técnica para implementarlo no es muy difícil: el autor aquí dedica su experiencia práctica a todos, como una forma de atraer nuevas ideas, ¡y espera ver otros métodos mejores!
A continuación se presentan primero algunos conocimientos básicos involucrados en este método y luego se utiliza un ejemplo para ilustrar la implementación específica.
1. Conceptos básicos
La metaclase (metaclase), también llamada tipo de referencia de clase (tipo de referencia de clase), puede considerarse como un tipo de clase, y el valor de una variable declarada con este tipo representa una clase. Por ejemplo:
tipo
TClass = Clase de TObject;
Esto declara un tipo de metaclase. Entonces puedes tener declaraciones de variables como esta:
var
Clase A: Clase T;
Entonces, puedes usarlo así:
Clase A := TObject;
o:
Clase A := TButton;
o:
Clase A := TForm;
etc.
Debido a que TClass es una metaclase de tipo TObject, y TButton, TForm, etc. se derivan de TObject, valores como TButton y TForm son aceptables para AClass.
Luego, podemos usar la idea de polimorfismo y usar de manera flexible la variable de clase AClass. Este es también el conocimiento básico para la implementación específica a continuación.
2. Implementación específica
El primer paso es crear una clase abstracta:
Usamos una declaración tan simple. La clase abstracta solo proporciona un método abstracto, pero no afecta nuestra descripción del problema:
TMyBaseForm = Clase(TForm)
Protegido
función GetTitle: pchar; resumen;
fin;
MyBaseFormClass = Clase de TMyBaseForm;
No analicemos cuántos métodos e interfaces prácticos proporciona una clase tan abstracta, porque lo que queremos discutir es una viabilidad técnica. Supongamos que la intención original del autor al definir esta interfaz es obtener cualquier número de títulos cambiantes, y que el valor de retorno específico de GetTitle debe ser implementado mediante subclases. Además, el autor también espera que el código de la subclase pueda implementarse en un Dll y separarse del programa principal; este método tiene la apariencia de un complemento y también puede implementar algunas características de Plug&Play. ¿No es muy atractivo? Entonces, ¿qué deberías hacer a continuación?
Primero, el programa principal y el programa Dll deben incluir las unidades declaradas anteriormente. Luego, el programa principal es responsable de implementar un controlador: cargar dinámicamente Dll y cargar dinámicamente clases y Dll es responsable de implementar subclases.
Hablemos primero de Dll. ¿Qué debería hacer Dll?
El segundo paso es exportar la subclase en Dll :
Diseñamos las siguientes dos funciones exportadas:
1. función GetClassCount: entero;
Dígale a la persona que llama que hay varias subclases en esta DLL;
2. función GetClassTypeByIndex(const iIndex: entero;
var ClassType: MyBaseFormClass): WordBool;
Obtenga una subclase específica por índice. Tenga en cuenta que el tipo de ClassType aquí es MyBaseFormClass, lo que indica que su valor será una clase definida heredada de TMyBaseForm.
Aquí hay una posible implementación de ellos:
función GetClassCount: entero;
comenzar
resultado := 3; // Indica que se exportan 3 clases en este Dll
fin;
función GetClassTypeByIndex(const iIndex: entero;
var ClassType: MyBaseFormClass): WordBool;
comenzar
resultado: = Verdadero;
caso iÍndice de
0: Tipo de clase := TFrmTest1;
1: Tipo de clase := TFrmTest2;
2: Tipo de clase := TFrmTest3;
demás
resultado := Falso;
fin;
fin;
Por supuesto, las unidades donde se encuentran TFrmTest1, TFrmTest2 y TFrmTest3 deben incluirse en la lista de Uso de la unidad. La implementación de TFrmTest1 puede ser así:
TFrmTest1 = Clase(TMyBaseForm)
protegido
función GetTitle: PChar;
fin;
función TFrmTest1.GetTitle: Pchar;
comenzar
resultado := 'Hola desde TFrmTest1';
fin;
Finalmente, no olvide agregar GetClassCount y GetClassByIndex a la lista de Exportaciones. Luego, al crear el proyecto Dll, marque "usar paquete de tiempo de ejecución" en el paquete de opciones del Proyecto. Las razones específicas se discutirán más adelante.
Hasta ahora, el trabajo en Dll ha llegado a su fin.
El tercer paso es la implementación del motor controlador del programa principal:
Este paso es relativamente fácil: no es más que cargar dinámicamente el DLL, luego llamar a la función GetClassCount y luego llamar a GetClassByIndex. Código clave:
Var Clase A: TMyBaseClass;
Formulario A: TMyBaseForm;
Yo, iCount: entero;
blResultado: booleano;
comenzar
//Omita la parte sobre cargar la biblioteca dinámica, suponiendo que FPGetClassProc apunta a la función GetClassCount y FPGetClassByIndexProc apunta a GetClassByIndex, entonces:
iCount := FPGetClassProc;
para I := 0 a iCount ?C 1 hacer
comenzar
AClass := FPGetClassByIndex(I, blResult);
si blResult entonces
comenzar
AForm := AClass.Create(aplicación);
AForm.Caption := AForm.GetTitle;
AForm.Mostrar;
fin;
fin;
//…
fin;
Tenga en cuenta que, al igual que Dll, también debe elegir utilizar el paquete de tiempo de ejecución al crear el archivo de salida. Esto se debe a que no usar el paquete de tiempo de ejecución dará como resultado múltiples copias de la misma clase en la memoria, por lo que usar el operador Is en ellas devolverá False.
Musicwind®@HangZhou.Zhejiang.China
2001-11-01
Más artículos
[ Fin del artículo]