Creando una dll en .Net para Visual Basic 6

Este post pretende ser un compendio de alguna de las cosas que aprendí al respecto de cómo crear una dll en .Net que sea usable desde VisualBasic 6. La necesidad de hacer tal cosa, en este caso, se originó por la imposibilidad de llamar a una actualización de una librería que maneja de un sistema de pago con tarjeta desde un código legado en VB6. La solución pasa por crear una librería que sirve de puente entre el programa en VB6 y la librería del sistema de pago.

Las referencias que he usado son:

Para conseguir nuestro objetivos debemos crear un interface y una clase que la implemente. La interface deberá cumplir los siguientes requisitos:

  • deberá ser pública
  • cualquier miembro que no pertenezca a la interfaz no será visible en VB6 (Existe la posibilidad de que COM interop genere el interfaz que contenga todos los miembros de la clase, pero es mejor hacerlo nosotros explícitamente)
  • Cada uno de los miembros del interfaz debe tener un atributo DispId. Dicho atributo acepta como parámetro un entero, que identifica cada una de las propiedades. Dentro de la misma interface los números no se pueden repetir. Si se repite sólo será visible uno de los miembros.
  • El interface deberá también tener el atributo Guid que identifica la clase dentro del registro del Windows. Hay múltiples formas de crear Guids: webs, plugins propios o de terceros, macros, o utilidades de Microsoft
  • Todos los miembros públicos del interfaz serán visibles en VB6: si queremos ocultar alguno podemos usar el atributo ComVisibleAttribute

Por otra parte la clase deberá cumplir estos otros requisitos:

  • Ser pública.
  • Los métodos y propiedades que queramos exponer deben ser públicos, a lo cual ya estamos obligados por el interface.
  • Podemos seguir teniendo miembros con otros ámbitos para uso interno (vamos, no es necesario escribir código espaguetti) pero sólo lo público será visible desde VB6.
  • La clase no sólo implementará el anterior interfaz, sino que además, en caso de que implemente más de uno, deberá se el primero de los interfaces.
  • Para que los clientes COM puedan instanciar objetos, la clase deberá tener, como mínimo, un constructor público sin parámetros. Los constructores con parámetros también se admiten, pero sólo podrán ser invocados dentro de código administrado .Net, lo cual no es el caso.

Por último, deberemos decirle a .Net que en el momento de compilar genere una librería de tipos que tiene la extensión .tlb. Para ello, en Propiedades del Proyecto > pestaña Generar seleccionaremos ‘Registrar para interoperabilidad COM’

vb6dll2

Si estamos programando en Visual Basic .Net podremos selecciona la plantilla de proyecto COMClass en el momento de crear la clase. Esta plantilla generara código que incluye todos los atributos mencionados, y establece las propiedades adecuadas del proyecto, ahorrándonos así el trabajo de hacerlo a mano.

Este ejemplo simplemente funciona como un puente entre VB6 y la nueva librería, y no aporta nueva funcionalidad. Por ello, me limité a añadir ‘Bridge’ a los nombres de las clases (quizá no es la mejor opción). Como se puede ver en el ejemplo, además, hay varias clases en juego, y es posible devolver a VB6 cualquiera de las clases que hayamos implementado bajo las condiciones anteriores.

Nuestro interface quedaría algo así como:

namespace LibPagoBridge {

    [Guid("4F52E06E-29C6-4168-8AC2-F836CD7A1C4A")]
    public interface ILibPagoBridge {
        [DispId(1)]
        ResultBridge InitializeDevice(string clientId, string lang, string posId, string storeId);

        [DispId(2)]
        ResultBridge BeginSellTransaction(string clientId, string lang, string posId, string storeId, string amount, string ticketNumber);

        [DispId(3)]
        NextMessageBridge GetNextMessage(string clientId, string lang, string posId, string storeId);

        [DispId(4)]
        ResultBridge BeginDevolution(string clientId, string lang, string posId, string storeId, string amount, string ticketNumber);

        [DispId(5)]
        bool Log { get; set; }

        [DispId(6)]
        ResultBridge CallSpecificFunction(string clientId, string lang, string posId, string storeId, int function1, int modifier, string parameter1, string parameter2, string parameter3);
    }
}

La clase, por otra parte, quedaría como:


[ClassInterface(ClassInterfaceType.None)]
[Guid("64B7C116-BA68-4EE0-8340-74F64846CB3D")]
public class LibPagoBridge: ILibPagoBridge {
    public LibPagoBridge() {

    }

    public bool Log {
        get;
        set;
    }
    public ResultBridge InitializeDevice(string clientId, string lang, string posId, string storeId) {
        // code
    }

    public ResultBridge BeginSellTransaction(string clientId, string lang, string posId, string storeId, string amount, string ticketNumber) {
        // code
    }

    public ResultBridge BeginDevolution(string clientId, string lang, string posId, string storeId, string amount, string ticketNumber) {
        // code
    }

    public NextMessageBridge GetNextMessage(string clientId, string lang, string posId, string storeId) {
        // code
    }

    public ResultBridge CallSpecificFunction(string clientId, string lang, string posId, string storeId, int function, int modifier, string parameter1, string parameter2, string parameter3) {
        // code
    }
}

Para usar la librería deberemos registrarla en el cliente. En nuestro ejemplo era un Windows XP, pero la técnica será similar en otros Windows. Para ello usaremos la aplicación RegAsm.exe del propio .Net. El directorio donde se encuentra la utilidad variará según la versión instalada del framework. Nótese que además de la dll tendremos que indicar que use la librería de tipos .tlb que habremos creado al compilar nuestro proyecto.

El comando será similar al siguiente (siendo LibPagoBridge.dll la librería a registrar).

"c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\Documents and Settings\Company\Mis documentos\Projects\LibPagoVB6\LibPagoBridge\LibPagoBridge.dll" /tlb:"C:\Documents and Settings\Company\Mis documentos\Projects\LibPagoVB6\LibPagoBridge\LibPagoBridge.tlb"

Si deseamos poner la dll en otro directorio distinto al de la aplicación cliente deberemos usar el parámetro /Codebase.

En el caso de que deseemos deregistrar la librería el comando es similar, pero usando el parámetro /unregister.

"c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\Documents and Settings\Company\Mis documentos\Projects\LibPagoVB6\LibPagoBridge\LibPagoBridge.dll" /unregister

Tras registrar la librería ya estará disponible para seleccionar en la lista de referencias disponibles del IDE de Visual Basic 6. Una vez agregada al proyecto, podremos usarla sin problemas. Un ejemplo de código sería:

Private Sub cmdCallSpecificFunction_Click()
    On Error GoTo Handler

    Dim Result As LibPagoBridge.ResultBridge
    Dim Bridge As LibPagoBridge.LibPagoBridge

    Set Bridge = New LibPagoBridge.LibPagoBridge
    Bridge.Log = True
    Rem simulamos un duplicado de ticket
    Set Result = Bridge.CallSpecificFunction("clientId", "lang", "posId,", "storeId", 1, 0, "", "3232", "")
    MsgBox Result.CodeDescription

    Exit Sub

Handler:
    MsgBox (Err.Description)
End Sub
Anuncios
Tagged with: , , ,
Publicado en Programacion
5 comments on “Creando una dll en .Net para Visual Basic 6
  1. Martín dice:

    es necesario para que funcione luego el programa de vb6 que este instalado también el framework .net?

    • xurxof dice:

      Si, es necesario, puesto que la aplicación en VB6 simplemente llama a una dll de .Net, pero es el intérprete de .Net el que ejecuta el código de dicha dll.

  2. Martín dice:

    Hice todo esactamente lo muestra aquí pero en VB6 agrego la referencia pero al querer usarla no me la reconoce como un objeto, como que en realidad no lo agrego al proyecto, faltará registrar algo mas para que VB6 lo reconozca?

  3. Excelente, muchas gracias, me saco de un gran lío.

Deixa a túa opinión

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: