crear dll estandar

16
Crear D ll estandar(windows) en visual basic 6.0 Incialmente este proceso fue desarrollado por Ron Petrusha y traducido por ElGuille. Primero lo Primero ADVERTENCIA: PUEDE HABER MUCHOS HORRORES POR LA TRUCCION DE LA PAGINA CON GOOGLE ¿Qué es una biblioteca de Windows Dynamic Link?. Una librería de enlace dinámico (DLL) es una biblioteca de funciones y procedimientos que se puede llamar desde una aplicación o archivo DLL otro. Uso de una biblioteca de esta forma tiene dos funciones principales: * Permite el intercambio de código. El mismo archivo DLL puede ser utilizada por muchos otros archivos DLL y las aplicaciones. La API de Win32, por ejemplo, se implementa como una serie de archivos DLL de Windows. * Permite el desarrollo basado en componentes y modular, lo que hace que el desarrollo y el proceso de actualización sea más fácil. Normalmente, cuando una biblioteca estática se utiliza en el desarrollo de aplicaciones, los módulos de la biblioteca debe estar vinculada a la aplicación final. Con la vinculación dinámica, los módulos pueden residir en un archivo independiente “”DLL” que se carga de forma dinámica, ya sea cuando se carga la aplicación o cuando sus funciones miembro son necesarios. Un archivo DLL también incluye un punto de entrada opcional, que se llama cuando se carga un proceso o subproceso o descarga el archivo DLL. Windows llama a este punto de entrada cuando se carga un proceso y descarga el archivo DLL. También llama a la puerta de entrada cuando el proceso crea o termina un hilo. Eso permite que el archivo DLL para realizar cualquiera por proceso y la inicialización de cada aplicación

Upload: miguelu2

Post on 15-Oct-2014

84 views

Category:

Documents


0 download

TRANSCRIPT

Crear Dll estandar(windows) en visual basic 6.0Incialmente este proceso fue desarrollado por Ron Petrusha y traducido por ElGuille. Primero lo Primero ADVERTENCIA: PUEDE HABER MUCHOS HORRORES POR LA TRUCCION DE LA PAGINA CON GOOGLE Qu es una biblioteca de Windows Dynamic Link?. Una librera de enlace dinmico (DLL) es una biblioteca de funciones y procedimientos que se puede llamar desde una aplicacin o archivo DLL otro. Uso de una biblioteca de esta forma tiene dos funciones principales: * Permite el intercambio de cdigo. El mismo archivo DLL puede ser utilizada por muchos otros archivos DLL y las aplicaciones. La API de Win32, por ejemplo, se implementa como una serie de archivos DLL de Windows. * Permite el desarrollo basado en componentes y modular, lo que hace que el desarrollo y el proceso de actualizacin sea ms fcil.

Normalmente, cuando una biblioteca esttica se utiliza en el desarrollo de aplicaciones, los mdulos de la biblioteca debe estar vinculada a la aplicacin final. Con la vinculacin dinmica, los mdulos pueden residir en un archivo independiente DLL que se carga de forma dinmica, ya sea cuando se carga la aplicacin o cuando sus funciones miembro son necesarios.

Un archivo DLL tambin incluye un punto de entrada opcional, que se llama cuando se carga un proceso o subproceso o descarga el archivo DLL. Windows llama a este punto de entrada cuando se carga un proceso y descarga el archivo DLL. Tambin llama a la puerta de entrada cuando el proceso crea o termina un hilo. Eso permite que el archivo DLL para realizar cualquiera por proceso y la inicializacin de cada aplicacin y limpieza. La sintaxis de este punto de entrada, que debe utilizar la convencin de llamada estndar (usado por defecto en Visual Basic), es: Public Function DllMain(hinstDLL As Long, fdwReason As Long, lpwReserved As Long) As Boolean

los Parmetros son: hInstDLL, es un long que contiene el identificador de instancia de la DLL. Este es el mismo mdulo de la DLL de manejar.

fdwReason, una constante que indica por qu el punto de entrada ha sido llamado. Los valores posibles son: DLL_PROCESS_ATTACH (1)

Un proceso se est cargando el archivo DLL. Cualquier inicializacin por proceso se debe realizar.DLL_THREAD_ATTACH (2)

El proceso est generando un nuevo hilo. Cualquier inicializacin por hilo debe ser realizada.DLL_THREAD_DETACH (3)

Un hilo es la salida. Cualquier limpieza por hilo debe ser realizada.DLL_PROCESS_DETACH (0)

Un proceso es extraer el archivo DLL, o el proceso est saliendo. Cualquier limpieza por proceso se debe realizar.lpvReserved

Es un long que proporciona ms informacin acerca de DLL_PROCESS_ATTACH y DLL_PROCESS_DETACH(que proporciona ms informacin acerca de fdwReason es DLL_THREAD_ATTACH o DLL_THREAD_DETACH.) Si fdwReason es DLL_PROCESS_ATTACH, esto es nada para las bibliotecas cargadas dinmicamente utilizando funciones como LoadLibrary y GetProcAddress, y no es nada para las bibliotecas de carga esttica por talones de la coleccin de proporcionar en tiempo de compilacin. Si fdwReason es DLL_PROCESS_DETACH, no es nada si la llamada es el resultado de una llamada a la funcin de Win32 FreeLibrary, y no es nada si el punto de entrada se llama durante la terminacin del proceso. El valor de retorno de la funcin slo tiene sentido si es fdwReason DLL_PROCESS_ATTACH. Si la inicializacin se realiza correctamente, la funcin debe devolver True, de lo contrario, debe devolver false. Tenga en cuenta que debido a que la funcin es un punto de entrada llamada por Windows, los valores de los argumentos pasados a la funcin son proporcionados por Windows. Adems, el punto de entrada no se llama cuando un hilo se termina con la funcin de Win32 TerminateThread, ni se llama cuando un proceso se termina con la funcin de Win32 TerminateProcess. El valor de retorno de la funcin slo tiene sentido si es fdwReason DLL_PROCESS_ATTACH. Si la inicializacin se realiza correctamente, la funcin debe devolver True, de lo contrario, debe devolver false. Tenga en cuenta que debido a que la funcin es un punto de entrada llamada por Windows, los valores de los argumentos pasados a la funcin son proporcionados por Windows. Adems, el punto de entrada no se llama cuando un hilo se termina con la funcin de Win32 TerminateThread, ni se llama cuando un proceso se termina con la funcin de Win32 TerminateProcess. El Cdigo DLL En el intento de desarrollar una DLL de Windows, vamos a crear una biblioteca muy simple de funciones matemticas. El siguiente es el cdigo del archivo DLL, que vamos a almacenar en un mdulo de cdigo (un archivo bas.) llamado MathLib:Option Explicit Public Const DLL_PROCESS_DETACH = 0

Public Const DLL_PROCESS_ATTACH = 1 Public Const DLL_THREAD_ATTACH = 2 Public Const DLL_THREAD_DETACH = 3 Public Function DllMain(hInst As Long, fdwReason As Long, lpvReserved As Long) As Boolean Select Case fdwReason Case DLL_PROCESS_DETACH ' No per-process cleanup needed Case DLL_PROCESS_ATTACH DllMain = True Case DLL_THREAD_ATTACH ' No per-thread initialization needed Case DLL_THREAD_DETACH ' No per-thread cleanup needed End Select End Function Public Function Increment(var As Integer) As Integer If Not IsNumeric(var) Then Err.Raise 5 Increment = var + 1 End Function Public Function Decrement(var As Integer) As Integer If Not IsNumeric(var) Then Err.Raise 5 Decrement = var - 1 End Function Public Function Square(var As Long) As Long If Not IsNumeric(var) Then Err.Raise 5 Square = var ^ 2 End Function

varias caractersticas sobre el cdigo vale la pena mencionar. La primera es que a pesar de que incluye un procedimiento DllMain, ningn proceso o por la inicializacin por subproceso debe realizarse. As DllMain simplemente devuelve True si se le llama con el argumento de fdwReason establece DLL_PROCESS_ATTACH. En segundo lugar, el punto de proporcionar un archivo DLL de Windows es permitir a otros idiomas para llamarlo. Para garantizar la interoperabilidad, queremos limitarnos a las caractersticas del lenguaje que la API de Win32 admite, por lo que nuestra DLL se puede llamar desde los entornos de desarrollo y muchas plataformas como sea posible. Podramos haber hecho cada uno de nuestros tres funciones matemticas ms flexible, por ejemplo, mediante la definicin tanto en el argumento de entrada y el valor de retorno como variantes. Eso habra permitido a la funcin para determinar el tipo de datos se deben interpretar los datos de entrada como, adems del tipo de datos se debe devolver. Sin embargo, la variante es un tipo de datos definidos por el COM, de componentes de Microsoft Modelo de objetos, y no es un tipo de datos de la API Win32 reconoce. As que en lugar, el cdigo utiliza el estndar de Win32 API de tipos de datos.

Tambin necesitar un programa de prueba que nos diga si nuestra DLL de Windows funciona correctamente. Para ello, se puede crear un proyecto EXE estndar con una forma y un mdulo de cdigo. El mdulo de cdigo consiste simplemente en las instrucciones Declare que definen las funciones que se encuentran en el archivo DLL:Public Declare Function Increment Lib "MathLib.dll" (var As Integer) As Integer Public Declare Function Decrement Lib "MathLib.dll" (var As Integer) As Integer Public Declare Function Square Lib "MathLib.dll" (var As Long) As Long

En lugar de simplemente especificando el nombre del archivo DLL en la clusula Lib, tambin debe agregar la ruta completa al directorio que contiene el archivo DLL. El cdigo del formulario realiza las llamadas a las funciones DLL:Option Explicit Dim incr As Integer Dim decr As Integer Dim sqr As Long Private Sub cmdDecrement_Click() decr = Increment(decr) cmdDecrement.Caption = "x = " & CStr(decr) End Sub Private Sub cmdIncrement_Click() incr = Increment(incr) cmdIncrement.Caption = "x = " & CStr(incr) End Sub Private Sub cmdSquare_Click() sqr = Square(srr) cmdSquare.Caption = "x = " & CStr(sqr) End Sub Private Sub Form_Load() incr = 1 decr = 100 sqr = 2 End Sub

El DLL de ActiveX Tipo de Proyecto Comencemos por crear un proyecto DLL ActiveX y ver lo que ocurre si tratamos de llamar como si fuera una norma DLL de Windows. Al crear un proyecto DLL ActiveX, Visual Basic agrega automticamente un mdulo de clase (un archivo. cls) a la misma. Puede cambiar el nombre si desea, pero no incluye ningn cdigo. En su lugar, agregue un mdulo de cdigo (un archivo. BAS) para el proyecto, agregar el cdigo del archivo DLL

y, a continuacin, compile la DLL. Al ejecutar la aplicacin de prueba DLL, el dilogo de mensaje de error que se muestra en la Figura 1 aparece. El mensaje de error indica que, aunque se encontr el archivo DLL, la funcin especfica llamada (incremento) no lo era. Ahora Si, una vez leido algo de la teoria vamos a lo nuestro.

Paso 1. Crear copia de LINK.exe con el nombre LinkLnk.exe Lo primero que tenemos que hacer antes de crear nuestra propia versin del enlazador (linker), es hacer una copia del programa LINK.exe, para cambiarle el nombre a esa copia, ya que ese nuevo fichero ser el que usemos desde nuestra versin de LINK.EXE, esta copia es independiente de la que te coment antes. Para hacerlo, sigue estos pasos: 1. Sitate en el directorio de Visual Basic (por ejemplo C:\Archivos de programa\Microsoft Visual Studio\VB98) 2. Selecciona el fichero LINK.EXE 3. Copia y pega 4. A la copia, cmbiale el nombre a LinkLnk.EXE Una vez hecho esto, el contenido de la carpeta de Visual Basic 6.0 ser como el de esta figura:

Paso 2. Crear nuestra propia versin de LINK.exe Ahora debemos crear nuestra propia versin de LINK.exe 1. Crea un nuevo proyecto en Visual Basic 6.0 de tipo EXE estndar

2. Cambia el nombre del proyecto a LINK 3. Elimina el formulario que se crea de forma predeterminada 4. Aade un mdulo BAS y cmbiale el nombre a MLINK.bas 5. En el men Proyecto, selecciona Propiedades... 6. En el combo "Objeto inicial", selecciona Sub Main 7. Pulsa Aceptar para aceptar el cambio 8. En el men Proyecto, selecciona Referencias... 9. Marca la casilla de Microsoft Scripting Runtime 10. Pulsa en Aceptar 11. En el mdulo pega el cdigo mostrado en el listado 1 12. Complalo (men Archivo>Generar Link.exe...) 13. Copia el LINK.EXE creado por este proyecto y pgalo en la carpeta de Visual Basic 6.0, te pedir confirmacin de si quieres sobrescribirlo, dile que s

'----------------------------------------------------------------------------' Link.exe (27/Dic/05) ' Wrapper para el Link de VB6 ' Basado en el cdigo original de Ron Petrusha ' http://www.windowsdevcenter.com/pub/a/windows/2005/04/26/crea te_dll.html ' ' Versin reducida (sin escribir en un .LOG) (25/Ene/06) ' para publicar en mi sitio ' ' Guillermo 'guille' Som, 2005-2006 '----------------------------------------------------------------------------Option Explicit Public Sub Main() Dim SpecialLink As Boolean, fCPL As Boolean, fResource As Boolean Dim intPos As Integer Dim strCmd As String Dim strPath As String Dim strFileContents As String Dim strDefFile As String, strResFile As String Dim oFS As New Scripting.FileSystemObject Dim fld As Folder

Dim fil As File Dim tsDef As TextStream strCmd = Command$ ' Determine if .DEF file exists ' ' Extract path from first .obj argument intPos = InStr(1, strCmd, ".OBJ", vbTextCompare) strPath = Mid$(strCmd, 2, intPos + 2) ' Esto solo vale para VB6 intPos = InStrRev(strPath, "\") strPath = Left$(strPath, intPos - 1) ' Open folder Set fld = oFS.GetFolder(strPath) ' Get files in folder For Each fil In fld.Files If UCase$(oFS.GetExtensionName(fil)) = "DEF" ThenstrDefFile = fil SpecialLink = True

End If If UCase$(oFS.GetExtensionName(fil)) = "RES" ThenstrResFile = fil fResource = True

End If If SpecialLink And fResource Then Exit For Next ' Change command line arguments if flag set If SpecialLink Then ' Determine contents of .DEF file Set tsDef = oFS.OpenTextFile(strDefFile) strFileContents = tsDef.ReadAll If InStr(1, strFileContents, "CplApplet", vbTextCompare) > 0 Then fCPL = True End If ' Add module definition before /DLL switchintPos = InStr(1, strCmd, "/DLL", vbTextCompare)

If intPos > 0 ThenstrCmd = Left$(strCmd, intPos - 1) & _

" /DEF:" & Chr$(34) & strDefFile & Chr$(34) & " " & _ Mid$(strCmd, intPos) End If

' Include .RES file if one exists If fResource Then intPos = InStr(1, strCmd, "/ENTRY", vbTextCompare) strCmd = Left$(strCmd, intPos - 1) & Chr$(34) & strResFile & _ Chr$(34) & " " & Mid$(strCmd, intPos) End If ' If Control Panel applet, change "DLL" extension to "CPL" If fCPL ThenstrCmd = Replace(strCmd, ".dll", ".cpl", 1, ,

vbTextCompare) End IfstrCmd = strCmd & " /LINK50COMPAT"

End IfShell "linklnk.exe " & strCmd

If Err.Number 0 Then ' Error al llamar al LINKerErr.Clear

End If End Sub Nota: Si quieres usar un icono para el ejecutable diferente al creado por el VB6, puedes hacer lo siguiente: -Aade un formulario al proyecto. -Cambia el icono del formulario por el que quieras usar. -En el cuado de propiedades de las propiedades del proyecto (men Proyecto>Propiedades de Link...), selecciona la ficha Generar, y selecciona ese formulario del combo que hay junto a Icono. -El Objeto inicial (de la ficha General) debe seguir siendo Sub Main. -Compilar el proyecto y el ejecutable tendr el icono indicado.

Ahora cuando quieras crear una DLL normal (al estilo de las del API de Windows), debes hacer lo siguiente: Paso 3. Crear una DLL normal con Visual Basic 6.0 1. Crea un nuevo proyecto del tipo DLL ActiveX 2. Aade un mdulo BAS 3. Escribe en ese mdulo las funciones o procedimientos Sub que quieras "exportar" como parte de la DLL (deben ser Public). 4. Crea un fichero con el mismo nombre del proyecto que tenga la extensin .DEF. 5. La estructura (o formato) de ese fichero es el mostrado en el listado 2. 6. Junto a NAME escribe el nombre del proyecto (sin extensin). 7. Junto a LIBRARY escribe el nombre que quieras (debe ser un nombre vlido, no uses espacios, etc.). 8. En DESCRIPTION escribe la descripcin de la librera (dentro de comillas dobles). 9. En EXPORTS debes indicar los nombres de las funciones o Sub que has creado, cada una de esas funciones o Sub deben llevar seguida @ y un nmero correlativo a partir del nmero 1. 10. Gurdalo y ya puedes compilar el proyecto creado como DLL.

NAME el_nombre_del_proyecto LIBRARY el_nombre_que_quieras DESCRIPTION "La descripcin que quieras usar" EXPORTS Nombre_Funcin_o_Sub @1 Otro_nombre_Funcin_o_Sub @2

Paso 4. Usar la DLL recin creada desde otro proyecto de VB6 Ahora vamos a usar desde el propio VB6 la DLL que acabamos de crear. 1. Crea un nuevo proyecto de tipo EXE estndar 2. Escribe los Declare para acceder a las funciones como si de una DLL de Windows se tratara 3. Por ejemplo, si tenemos una DLL llamada Prueba.dll en la que hemos definido una funcin llamada Saludo que devuelve un String, la debes definir de esta forma: o Private Declare Function Saludo Lib "Prueba.dll" () As String 4. La librera Prueba.dll debe estar en el mismo directorio que el ejecutable de este proyecto. 5. Escribe un cdigo que use esa funcin de la misma forma que lo haras con cualquier otra funcin, por ejemplo: o MsgBox Saludo

6. Al ejecutarlo, vers que se muestra lo que la funcin Saludo devuelva, (ahora veremos un ejemplo real). 7. En realidad las cadenas debemos "tratarlas" un poco antes de usarlas.

Cdigo de ejemplo de una DLL en VB6 Para crear la DLL seguiremos los pasos indicados en Paso 4, que son: -Crear un nuevo proyecto del tipo DLL ActiveX, (cambia el nombre a Prueba). -Aade un mdulo BAS, (cambia el nombre a MPrueba). -En ese mdulo pega el cdigo del listado 4. -Con un editor de textos crea un fichero llamado Prueba.DEF y aade el texto mostrado en el listado 5. -El fichero .DEF debe estar en el mismo directorio del proyecto Prueba.vbp. -Compila el proyecto, si todo ha ido bien, tendrs un fichero llamado Prueba.dll -Esta DLL la usaremos en nuestro proyecto de prueba desde VB6 y es la misma DLL usada en el cdigo de ejemplo de C/C++ del listado 3. '----------------------------------------------------------------------------' DLL de prueba para crearla desde VB6 (25/Ene/06) ' Esta DLL se usar como una "normal" no de ActiveX DLL ' ' Guillermo 'guille' Som, 2006 '----------------------------------------------------------------------------Option Explicit Public Function Saludo() As String Saludo = "Hola desde la DLL Prueba" End Function Public Function Suma(ByVal n1 As Double, ByVal n2 As Double) As DoubleSuma = n1 + n2

End Function Listado 4. El cdigo de la DLL a crear con VB6 NAME Prueba LIBRARY elGuille DESCRIPTION "Prueba de DLL creada con VB6"EXPORTS Saludo @1

Suma @2

Y ya tenemos nuestra DLL creada, ahora vamos a escribir un proyecto en VB6 para usar esa DLL, lo haremos de la misma forma que usaramos cualquier DLL "normal" de Windows. Cdigo del proyecto de prueba hecho con VB6y y y y y y y

Crea un nuevo proyecto de tipo EXE estndar. En el formulario aade 2 botones, tres etiquetas y tres cajas de textos para que tenga el aspecto de la figura 2. El botn de Saludar se llama cmdSaludo El botn Sumar se llama cmdSumar Las cajas de texto tendrn los nombres: txtNum1, txtNum2 y txtRes (que es la caja de abajo) En el formulario aade el cdigo del listado 6 Pulsa F5 y vers que todo funciona bien, siempre que la DLL est en el mismo directorio que este proyecto o bien, la DLL puede estar en cualquier directorio incluido en el PATH del sistema, por ejemplo en el directorio de Windows.

'----------------------------------------------------------------------------' Proyecto de prueba de la librera Prueba.dll creada con VB6 (25/Ene/06) ' ' Guillermo 'guille' Som, 2006 '----------------------------------------------------------------------------Option Explicit ' Las declaraciones de las funciones de la DLL

Private Declare Function Saludo Lib "Prueba.dll" () As String Private Declare Function Suma Lib "Prueba.dll" (ByVal n1 As Double, ByVal n2 As Double) As Double Private Sub cmdSaludo_Click() Dim s As Strings = Saludo

' Las cadenas de VB6 son Unicode y al usarla desde una DLL ' se hace un folln... as que debemos quitarles los Chr$(0) ' que tenga en medios = MTrim(s) MsgBox s

End Sub Private Sub cmdSumar_Click() Dim n1 As Double Dim n2 As Doublen1 = Val(txtNum1.Text) n2 = Val(txtNum2.Text) txtRes.Text = Suma(n1, n2)

End Sub Private Function MTrim(ByVal s As String) As String Dim i As Long Dim res As String For i = 1 To Len(s) If Mid$(s, i, 1) Chr$(0) Thenres = res & Mid$(s, i, 1)

End If NextMTrim = res

End Function