none
Error Agregar referencia en vb.net - .dll Delphi RRS feed

  • Pregunta

  • Hola,

    Tengo un proyecto en vb.net 2010, queira añadir una referencia a una .dll programada en Delphi.

    Aparece el error "No se puede agregar una referencia ...." "Asegurese de que tiene acceso al archivo y de que es un ensamblado o componente COM valido."

    Alguna idea? ... No es posible añadir una dll de delphi?

    muchas gracias,

    viernes, 10 de abril de 2015 12:16

Respuestas

  • Con la opción de "agregar referencia" en VB.Net, únicamente se pueden agregar DLLs que sean de código gestionado de .Net (cosa que Delphi no puede generar), o bien objetos COM debidamente registrados en el registro de Windows (cosa que según he leído se puede generar con esfuerzo en Delphi pero que no ocurre de manera predeterminada).

    Así pues, si se trata de una DLL que es simpemente un binario de Windows, no puedes usar la opción de Agregar una Referencia. Tendrás que recurrir a escribir en tu código fuente un <DllImport(...)>, o bien al antiguo Declare Function para poderla usar desde VB a través de Platform/Invoke.

    viernes, 10 de abril de 2015 13:13
  • Si se sabe que la DLL funciona bien, pero sin embargo da un error al llamarla mediante DllImport, típicamente significa que hay un problema en el paso de parámetros.

    Por ejemplo, puede ser que la DLL esté realizando el paso al estilo Pascal y que en el DllImport hayas dejado el formato predeterminado (CDECL). También puede ser un problema de formato de strings (por defecto y si no dices lo contrario el Marshalling del DllImport convierte los strings de .Net a punteros a cadenas terminadas por caracter cero, es decir el estilo de C, que no sé si coincide con el de Delphi). También puede ser problema de tamaño de los parámetros (los Integer de VB.NET son de 32 bits, ¿sabes si en Delphi coincide el tamaño?).

    En fin, que usar el <DllImport> requiere bastantes conocimientos y una adecuada parametrización. Hay que conocer el formato de la trama de pila de la DLL a la que se dirige, incluyendo el formato y tamaño de todos los parámetros y resultados, y parametrizar adecuadamente el DllImport para que coincida. Los formatos que el DllImport toma por defecto cuando no le dices nada es muy probable que no coincidan con los que espera la DLL, y eso hace que se produzca un error grave y el programa se cierre.

    • Marcado como respuesta Jordisc lunes, 13 de abril de 2015 14:18
    sábado, 11 de abril de 2015 6:15

Todas las respuestas

  • Con la opción de "agregar referencia" en VB.Net, únicamente se pueden agregar DLLs que sean de código gestionado de .Net (cosa que Delphi no puede generar), o bien objetos COM debidamente registrados en el registro de Windows (cosa que según he leído se puede generar con esfuerzo en Delphi pero que no ocurre de manera predeterminada).

    Así pues, si se trata de una DLL que es simpemente un binario de Windows, no puedes usar la opción de Agregar una Referencia. Tendrás que recurrir a escribir en tu código fuente un <DllImport(...)>, o bien al antiguo Declare Function para poderla usar desde VB a través de Platform/Invoke.

    viernes, 10 de abril de 2015 13:13
  • Hola Alberto,

    ok! claro, entiendo...

    He probado con DLLImport, pero directamente aparece un error que no responde y se cierra, he probado dll Import con otra DLL (user32.dll) y funciona correctamente. Seguire probando, pero a ver si sera la DLL de Delphi, porque mucho secreto no parece tener.

        <DllImport("User32.dll")> Public Shared Function _
                MessageBox(ByVal hWnd As Integer, _
                ByVal txt As String, ByVal caption As String, _
                ByVal typ As Integer) As Integer
        End Function

    Esto me funciona perfecto, con la otra no :(

    Muchas gracias!

    viernes, 10 de abril de 2015 16:17
  • Si se sabe que la DLL funciona bien, pero sin embargo da un error al llamarla mediante DllImport, típicamente significa que hay un problema en el paso de parámetros.

    Por ejemplo, puede ser que la DLL esté realizando el paso al estilo Pascal y que en el DllImport hayas dejado el formato predeterminado (CDECL). También puede ser un problema de formato de strings (por defecto y si no dices lo contrario el Marshalling del DllImport convierte los strings de .Net a punteros a cadenas terminadas por caracter cero, es decir el estilo de C, que no sé si coincide con el de Delphi). También puede ser problema de tamaño de los parámetros (los Integer de VB.NET son de 32 bits, ¿sabes si en Delphi coincide el tamaño?).

    En fin, que usar el <DllImport> requiere bastantes conocimientos y una adecuada parametrización. Hay que conocer el formato de la trama de pila de la DLL a la que se dirige, incluyendo el formato y tamaño de todos los parámetros y resultados, y parametrizar adecuadamente el DllImport para que coincida. Los formatos que el DllImport toma por defecto cuando no le dices nada es muy probable que no coincidan con los que espera la DLL, y eso hace que se produzca un error grave y el programa se cierre.

    • Marcado como respuesta Jordisc lunes, 13 de abril de 2015 14:18
    sábado, 11 de abril de 2015 6:15
  • Tengo más info de la DLL, (desde delphi funciona perfectamente) e imagino que sera lo que me estas comentado tu de los tipos, concretamente los string como punteros.

    El metodo que he de usar es este en Delphi

         Procedure CargarIniListadosDllimpresion (NombreDetalleIni:string; NombresParamId:Array of string;
                                                                           ValorCamposId:Array of string );

    Yo usaba asi el DLLImport :

        <DllImport("DLLimpresion.dll")> Public Shared Sub _
                CargarIniListadosDllimpresion(ByVal NombreDetalleIni As String, _
                ByVal NombresParamId As String(), ByVal ValorCamposId As String())

    Entonces claro, los string me los estara tratando como punteros!!! He probado varias combinaciones y he llegado a esto :

        <DllImport("CijamDLLimpresion.dll")> Public Shared Sub CargarIniListadosDllimpresion( _
                        <MarshalAs(UnmanagedType.LPStr)> NombreDetalleIni As String, _
                        <MarshalAs(UnmanagedType.LPStr)> NombresParamId As String(), _
                        <MarshalAs(UnmanagedType.LPStr)> ValorCamposId As String())

    Ya no da un error grave, pero tampoco funciona, :( aparece este mensaje!

    No se pueden calcular las referencias de 'parameter #2': Combinación de tipos administrado y no administrado no válida (solo se pueden calcular las referencias de las matrices como LPArray, ByValArray o SafeArray).

    Antes habia probado con LPArray ara los arrays de strings, porque he parecia lo correcto, pero salta el error grave!

        <DllImport("CijamDLLimpresion.dll")> Public Shared Sub CargarIniListadosDllimpresion( _
                        <MarshalAs(UnmanagedType.LPStr)> NombreDetalleIni As String, _
                        <MarshalAs(UnmanagedType.LPArray)> NombresParamId As String(), _
                        <MarshalAs(UnmanagedType.LPArray)> ValorCamposId As String())


    Jordi Sanchez

    lunes, 13 de abril de 2015 14:18