Visual Basic 3.0: crear DLL normal de Windows

Como no consigo hacer bien DLL con los programas de compilar en C, por culpa sobre todo de las rutas de librerías de cabeceras de LabView y OpenCV, he encontrado un método para hacer DLL con Visual Basic 6.0 en la página de elGuille.info y que luego sirve para llamar desde LabView. Lo único que las cadenas de caracteres no he conseguido llamarlas bien, sólo numéricas, y el propio Guille te dice que tampoco lo ha conseguido llamar desde C.

Las librerías DLL se pueden llamar desde C/C++, .NET (VB y C#), desde luego desde el mismo VB y algún lenguaje más seguramente, al ser las normales de windows, pero son los ejemplos que te puedes en contrar en la página de elGuille.info . Su ejemplo está sacado a la vez de otra página en Ingles, el original Aquí.

Yo haré un resumen de su resumen y comentaré algún detallito por si se tiene menos ideas de VB6, para crear mas rápidamente la DLL y poder utilizarla con LabView. Por favor visita su página si te interesa saber más como llamar la DLL desde C++ o .NET (VB y C#). elGuille.info

  • Paso 1: crear copia de LINK.exe con el nombre LinkLnk.exe

Vamos a manipular el lincador del Visual Basic 6 con lo que haremos una copia de seguridad, para que luego podamos utilizarlo como antes.

  1. Sitúate 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, cámbiale el nombre a LinkLnk.EXE.
  5. [yo para luego no tener que acordarme que nombre tenía, cogí una copia de LINK.exe y de C2.exe (hay otro método para cambiarlo tambien pero no se va hacer) a otra caperta aparte comprimida y así tener los originales con los nombres originales siempre listo por si acaso].

Figura 1. Directorio VB6 tras cambiar nombre

  • Paso 2: crear nuestra propia versión de LINK.exe
  1. Crea un nuevo proyecto en Visual Basic 6.0 de tipo EXE estándar.
  2. Cambia el nombre del proyecto a LINK (ratón sobre proyecto1 en la derecha podrás cambiarlo abajo en propiedades).
  3. Elimina el formulario que se crea de forma predeterminada (Form1, segundo botón quitar).
  4. Añade un módulo BAS y cámbiale el nombre a MLINK.bas (sobre Proyecto1 ahora llamado LINK, botón derecho, Agregar módulo normal y corriente).
  5. En el menú Proyecto, selecciona Propiedades, en el combo “Objeto inicial”, selecciona Sub Main (a mi me viene seleccionado por defecto). Pulsa Aceptar para aceptar el cambio.
  6. En el menú Proyecto, selecciona Referencias, Marca la casilla de Microsoft Scripting Runtime (hay muchas casillas pero por suerte está en orden, se supone que es un archivo dll guardado en C:/WINDOWS/system32/scrrun.dll) y Pulsa en Aceptar
  7. En el módulo (pestaña general y declaraciones) pega el código mostrado en el listado 1
  8. Compílalo (menú Archivo>Generar Link.exe…) (antes tendrias que haber guardado el proyecto en una carpeta aparte para que no se te lien los archivos generados del proyecto).
  9. Copia el LINK.EXE creado por este proyecto y pégalo en la carpeta de Visual Basic 6.0, te pedirá confirmación de si quieres sobrescribirlo, dile que sí. (YA QUE TENEMOS UNA COPIA DE SEGURIDAD HECHA ¿¿¿VERDAD???).
'------------------------------------------------------------------------------
' Link.exe                                                          (27/Dic/05)
' Wrapper para el Link de VB6
' Basado en el código original de Ron Petrusha
' http://www.windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html
'
' Versión 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" Then
            strDefFile = fil
            SpecialLink = True
        End If
        If UCase$(oFS.GetExtensionName(fil)) = "RES" Then
            strResFile = 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 switch
        intPos = InStr(1, strCmd, "/DLL", vbTextCompare)
        If intPos > 0 Then
            strCmd = 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 Then
            strCmd = Replace(strCmd, ".dll", ".cpl", 1, , vbTextCompare)
        End If

        strCmd = strCmd & " /LINK50COMPAT"

    End If

    Shell "linklnk.exe " & strCmd

    If Err.Number <> 0 Then
       ' Error al llamar al LINKer
       Err.Clear
    End If

End Sub

Listado 1. El código de LINK.EXE (versión personalizada de VB6)

Por favor visita elGuille.info para ver el código mejor si tienes algún problema al copiar.

Ya podemos Crear DLL normales con Visual Basic 6, haremos una de ejemplo que luego utilizaremos para llamar desde LabView.

  • Paso 3: crear una DLL normal con VB6
  1. Crear un nuevo proyecto del tipo DLL ActiveX, (por ejemplo cambia el nombre a Prueba).
  2. Añade un módulo BAS, (por ejemplo cambia el nombre a MPrueba, no borrar el que sale).
  3. Escribe en ese módulo las funciones o procedimientos Sub que quieras “exportar” como parte de la DLL (deben ser Public). (Por ejemplo en ese módulo pega el código del listado 4).
  4. Crea un fichero con el mismo nombre del proyecto que tenga la extensión .DEF. (por ejemplo Prueba.def y añade el texto mostrado en el listado 5.)

- El fichero .DEF debe estar en el mismo directorio del proyecto Prueba.vbp.

'------------------------------------------------------------------------------
' 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 Double
    Suma = n1 + n2
End Function

Listado 4. El código de la DLL a crear con VB6

NAME Prueba
LIBRARY elGuille
DESCRIPTION "Prueba de DLL creada con VB6"
EXPORTS Saludo @1
        Suma @2

Listado 5. El contenido del fichero Prueba.def

La estructura (o formato) de ese fichero es el mostrado en el listado 2.

NAME el_nombre_del_proyecto
LIBRARY el_nombre_que_quieras
DESCRIPTION "La descripción que quieras usar"
EXPORTS Nombre_Función_o_Sub @1
        Otro_nombre_Función_o_Sub @2

Listado 2. El formato del fichero .DEF

- Junto a NAME escribe el nombre del proyecto (sin extensión).

- Junto a LIBRARY escribe el nombre que quieras (debe ser un nombre válido, no uses espacios, etc.).

- En DESCRIPTION escribe la descripción de la librería (dentro de comillas dobles).

- 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 número correlativo a partir del número 1.

5.  Guárdalo y ya puedes compilar el proyecto creado como DLL, si todo ha salido bien tendras una DLL llamada Prueba.dll en el mismo directorio que el proyecto. Ya no hace falta tener el archivo .def junto al .dll para que funcione, pero es bueno tenerlo al lado para saber cuales son las funciones que se exportan.

Ya esta todo, ahora esa dll de Prueba la utilizaremos para el llamarla desde el LabView, si quieres llamarla desde el mismo Visual Basic con su formulario y todo o desde C++ o .NET (VB y C#) visita la página de elGuille.info

Etiquetas: ,

4 comentarios para “Visual Basic 3.0: crear DLL normal de Windows”

  1. shoe dice:

    bravaza esta informacion mi brother, te pasaste.

  2. Jose Antonio dice:

    Como seria el caso que quiera realizar el mismo proceso si deseo generar una dll de 16 bits?. (En visual basic 3.0)
    me escribes a xmenplus@hotmail.com
    Gracias

  3. weeberp dice:

    Pes la verdad que no tengo ni idea de si son 16 bits o menos o más lo que tengo aquí escrito y ya menos en visual basic 3.0.
    Ahora he aprendido hacer dll de forma normal, haciendo funciones y poder llamar las desde el exterior con microsoft visual C++ 6.0 y con Dev-C++ o codeblock que es practicamente igual pero para linuz tambien.

    Lo que si utilizo mucho para ver si una dll tiene funciones que se pueden llamar del exterior y si las he hecho bien, y las llamadas que hace… es el programita Dependency Walker 2.2, lo recomiendo.

  4. Isaías Bórquez dice:

    How I can return Strings?

    Thanks to LaVolpe in PlanetSourceCode, I now Know how to pass a string to and from a VB DLL compiled as standard DLL.

    Specifically, when passing a string to the DLL, the DLL needs to convert the string as follows:

    SValue = StrConv(sValue, vbUnicode)

    When returning a string from the DLL, either via a passed variable in a Sub or as the return value of a Function, the DLL needs to convert the string as follows:

    sValue = StrConv(sValue, vbFromUnicode)

    or

    MyFunction = StrConv(sValue, vbFromUnicode)

    Steve Tesch

Deja un comentario