Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial paso a paso se explica cómo usar el IDE de Visual Studio para crear su propia biblioteca de vínculos dinámicos (DLL) escrita en Microsoft C++ (MSVC) y cómo usar el archivo DLL desde otra aplicación de C++. Los archivos DLL, también conocidos como bibliotecas compartidas en sistemas operativos basados en UNIX, son uno de los tipos más útiles de componentes de Windows. Puede usarlos para compartir código y recursos y reducir el tamaño de las aplicaciones. Incluso los archivos DLL pueden facilitar el servicio y ampliar las aplicaciones.
En este tutorial, creará un archivo DLL que implementa algunas funciones matemáticas. A continuación, cree una aplicación de consola que use las funciones desde el archivo DLL. También obtendrá una introducción a algunas de las técnicas de programación y convenciones que se usan en los archivos DLL de Windows.
En este tutorial se describen los pasos siguientes:
- Cree un proyecto DLL en Visual Studio.
- Agregue funciones y variables exportadas al archivo DLL.
- Cree un proyecto de aplicación de consola en Visual Studio.
- Use las funciones y variables importadas desde el archivo DLL en la aplicación de consola.
- Ejecute la aplicación completada.
Al igual que una biblioteca vinculada estáticamente, un archivo DLL exporta variables, funciones y recursos por nombre. Una aplicación cliente importa los nombres para usar esas variables, funciones y recursos. A diferencia de una biblioteca vinculada estáticamente, Windows conecta las importaciones de tu aplicación a las exportaciones de un archivo DLL en tiempo de carga o en tiempo de ejecución, en lugar de conectarlas en tiempo de enlace. Windows requiere información adicional que no forma parte del modelo de compilación estándar de C++ para realizar estas conexiones. El compilador de MSVC implementa algunas extensiones específicas de Microsoft en C++ para proporcionar esta información adicional. Explicamos estas extensiones a medida que vamos.
En este tutorial se crean dos soluciones de Visual Studio: una que compila el archivo DLL y otra que compila la aplicación cliente. El archivo DLL usa la convención de llamada de C. Se puede llamar desde aplicaciones escritas en otros lenguajes de programación, siempre que la plataforma, las convenciones de llamada y las convenciones de vinculación coincidan. La aplicación cliente usa la vinculación implícita, donde Windows vincula la aplicación al archivo DLL en tiempo de carga. Esta vinculación permite a la aplicación llamar a las funciones proporcionadas por DLL igual que las funciones de una biblioteca vinculada estáticamente.
En este tutorial no se tratan algunas situaciones comunes. El código no muestra el uso de archivos DLL de C++ por otros lenguajes de programación. No muestra cómo crear un archivo DLL de solo recursos o cómo usar la vinculación explícita para cargar archivos DLL en tiempo de ejecución en lugar de en tiempo de carga. Tenga la seguridad de que puede usar MSVC y Visual Studio para hacer todas estas cosas.
Aunque el código del archivo DLL está escrito en C++, usamos interfaces de estilo C para las funciones exportadas. Hay dos razones principales por las que: en primer lugar, muchos otros lenguajes admiten importaciones de funciones de estilo C. La aplicación cliente no tiene que escribirse en C++. En segundo lugar, evita algunos problemas comunes relacionados con las clases exportadas y las funciones miembro. Es fácil cometer errores difíciles de diagnosticar al exportar clases, ya que todo lo que se menciona en una declaración de clase tiene que tener una instanciación que también se exporte. Esta restricción se aplica a archivos DLL, pero no a bibliotecas estáticas. Si tus clases tienen un estilo de datos simples o tradicionales, no deberías encontrarte con este problema.
Para obtener vínculos a más información sobre los archivos DLL, vea Creación de archivos DLL de C/C++ en Visual Studio. Para obtener más información sobre la vinculación implícita y la vinculación explícita, vea Determinar qué método de vinculación se va a usar. Para obtener información sobre cómo crear archivos DLL de C++ para usarlos con lenguajes de programación que usan convenciones de vinculación del lenguaje C, consulte Exportación de funciones de C++ para su uso en ejecutables del lenguaje C. Para obtener información sobre cómo crear archivos DLL para su uso con lenguajes .NET, vea Llamar a funciones DLL desde aplicaciones de Visual Basic.
Prerrequisitos
- Microsoft Windows 7 o posterior. Se recomienda la versión más reciente de Windows para obtener la mejor experiencia de desarrollo.
Visual Studio. Para obtener información sobre cómo descargar e instalar Visual Studio, consulte Instalación de Visual Studio. Al ejecutar el instalador, asegúrese de que la carga de trabajo Desarrollo de escritorio con C++ está activada. No se preocupe si no instaló esta carga de trabajo al instalar Visual Studio. Puede volver a ejecutar el instalador e instalarlo ahora.
- Visual Studio. Para obtener información sobre cómo descargar e instalar Visual Studio 2015, consulte Instalación de Visual Studio 2015. Use una instalación personalizada para instalar el compilador y las herramientas de C++, ya que no están instalados de forma predeterminada.
Conocimientos de los conceptos básicos del uso del IDE de Visual Studio. Si ha usado aplicaciones de escritorio de Windows antes, es probable que pueda mantenerse al día. Para obtener una introducción, consulte Paseo por características del IDE de Visual Studio.
Cierta familiaridad con el lenguaje C++. No te preocupes, no hacemos nada demasiado complicado.
Nota:
En este tutorial se da por supuesto que usa Visual Studio 2017, versión 15.9 o posterior. Algunas versiones anteriores de Visual Studio 2017 tenían defectos en las plantillas de código o usaban diálogos de interfaz de usuario diferentes. Para evitar problemas, use el Instalador de Visual Studio para actualizar Visual Studio 2017 a la versión 15.9 o posterior.
Creación del proyecto DLL
En el siguiente conjunto de tareas, creará un proyecto para el archivo DLL, agregará código y lo compilará. Para empezar, inicie el IDE de Visual Studio e inicie sesión si es necesario. Las instrucciones varían ligeramente en función de la versión de Visual Studio que use. Para ver los pasos de la versión preferida de Visual Studio, use el selector versión situado en la parte superior de la tabla de contenido de esta página.
Para crear un proyecto DLL en Visual Studio
En la barra de menús, seleccione Archivo>Nuevo>Proyecto para abrir el cuadro de diálogo Crear nuevo proyecto.
En la parte superior del cuadro de diálogo, establezca Lenguaje en C++, establezca Plataforma en Windows y establezca Tipo de proyecto en Biblioteca.
En la lista filtrada de tipos de proyecto, seleccione Biblioteca de vínculos dinámicos (DLL) y, a continuación, elija Siguiente.
En la página Configurar el nuevo proyecto , escriba MathLibrary en el cuadro Nombre del proyecto para especificar un nombre para el proyecto. Deje los valores predeterminados Ubicación y Nombre de la solución . Establezca Solución en Crear nueva solución. Desactive Colocar solución y proyecto en el mismo directorio si está activado.
Elija el botón Crear para crear el proyecto.
Cuando se crea la solución, puede ver el proyecto generado y los archivos de origen en la ventana Explorador de soluciones de Visual Studio.
Para crear un proyecto DLL en Visual Studio 2017
En la barra de menús, seleccione Archivo>Nuevo>Proyecto para abrir el cuadro de diálogo Nuevo proyecto.
En el panel izquierdo del cuadro de diálogo Nuevo proyecto , seleccione Instalado>Visual C++>Escritorio de Windows. En el panel central, seleccione Dynamic-Link Biblioteca (DLL). Escriba MathLibrary en el cuadro Nombre para especificar un nombre para el proyecto. Deje los valores predeterminados Ubicación y Nombre de la solución . Establezca Solución en Crear nueva solución. Marca Crear directorio para la solución si no está activado.
Elija el botón Aceptar para crear el proyecto.
Cuando se crea la solución, puede ver el proyecto generado y los archivos de origen en la ventana Explorador de soluciones de Visual Studio.
Para crear un proyecto DLL en Visual Studio 2015 y versiones anteriores
En la barra de menús, elija Archivo>nuevo>proyecto.
En el panel izquierdo del cuadro de diálogo Nuevo proyecto, expandaPlantillas instaladas> y seleccione Visual C++y, a continuación, en el panel central, seleccione Aplicación de consola Win32. Escriba MathLibrary en el cuadro De edición Nombre para especificar un nombre para el proyecto. Deje los valores predeterminados Ubicación y Nombre de la solución . Establezca Solución en Crear nueva solución. Marque Crear directorio para la solución si no está marcado.
Elija el botón Aceptar para descartar el cuadro de diálogo Nuevo proyecto e inicie el Asistente para aplicaciones Win32.
Elija el botón Siguiente. En la página Configuración de la aplicación , en Tipo de aplicación, seleccione DLL.
Elija el botón Finalizar para crear el proyecto.
Cuando el asistente complete la solución, puede ver el proyecto generado y los archivos de origen en la ventana Explorador de soluciones de Visual Studio.
En este momento, este archivo DLL no hace mucho. A continuación, creará un archivo de encabezado para declarar las funciones que exporta el archivo DLL y, a continuación, agregará las definiciones de función al archivo DLL para que sea más útil.
Para agregar un archivo de encabezado al archivo DLL
Para crear un archivo de encabezado para las funciones, en la barra de menús, elija ProjectAdd New Item (Agregar nuevo elemento>
En el cuadro de diálogo Agregar nuevo elemento , en el panel izquierdo, seleccione Visual C++. En el panel central, seleccione Archivo de encabezado (.h). Especifique
MathLibrary.hcomo nombre para el archivo de encabezado.
Elija el botón Agregar para generar un archivo de encabezado en blanco, que se muestra en una nueva ventana del editor.
Reemplace el contenido del archivo de encabezado por este código:
// MathLibrary.h - Contains declarations of math functions #pragma once #ifdef MATHLIBRARY_EXPORTS #define MATHLIBRARY_API __declspec(dllexport) #else #define MATHLIBRARY_API __declspec(dllimport) #endif // The Fibonacci recurrence relation describes a sequence F // where F(n) is { n = 0, a // { n = 1, b // { n > 1, F(n-2) + F(n-1) // for some initial integral values a and b. // If the sequence is initialized F(0) = 1, F(1) = 1, // then this relation produces the well-known Fibonacci // sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. extern "C" MATHLIBRARY_API void fibonacci_init( const unsigned long long a, const unsigned long long b); // Produce the next value in the sequence. // Returns true on success and updates current value and index; // false on overflow, leaves current value and index unchanged. extern "C" MATHLIBRARY_API bool fibonacci_next(); // Get the current value in the sequence. extern "C" MATHLIBRARY_API unsigned long long fibonacci_current(); // Get the position of the current value in the sequence. extern "C" MATHLIBRARY_API unsigned fibonacci_index();
Este archivo de encabezado declara algunas funciones para generar una secuencia generalizada de Fibonacci, dadas dos valores iniciales. Una llamada a fibonacci_init(1, 1) genera la conocida secuencia de números de Fibonacci.
Observe las instrucciones del preprocesador en la parte superior del archivo. La nueva plantilla de proyecto para un proyecto DLL agrega <PROJECTNAME>_EXPORTS a las macros de preprocesador definidas. En este ejemplo, Visual Studio define MATHLIBRARY_EXPORTS cuándo se compila el proyecto DLL MathLibrary.
Cuando se define la MATHLIBRARY_EXPORTS macro, la MATHLIBRARY_API macro establece el __declspec(dllexport) modificador en las declaraciones de función. Este modificador indica al compilador y al enlazador que exporte una función o variable desde el archivo DLL para su uso por parte de otras aplicaciones. Cuando MATHLIBRARY_EXPORTS no está definido, por ejemplo, cuando una aplicación cliente incluye el archivo de encabezado, MATHLIBRARY_API aplica el __declspec(dllimport) modificador a las declaraciones. Este modificador optimiza la importación de la función o variable en una aplicación. Para obtener más información, consulte dllexport, dllimport.
Para agregar una implementación al archivo DLL
En el Explorador de soluciones, haga clic con el botón derecho en el nodo Archivos de origen y elija Agregar>nuevo elemento. Cree un nuevo
.cpparchivo denominadoMathLibrary.cpp, de la misma manera que agregó un nuevo archivo de encabezado en el paso anterior.En la ventana del editor, seleccione la
MathLibrary.cpppestaña si ya está abierta. Si no es así, en el Explorador de soluciones, haga doble clicMathLibrary.cppen la carpeta Archivos de origen del proyecto MathLibrary para abrirlo.En el editor, reemplace el contenido del
MathLibrary.cpparchivo por el código siguiente:// MathLibrary.cpp : Defines the exported functions for the DLL. #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier #include <utility> #include <limits.h> #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) { index_ = 0; current_ = a; previous_ = b; // see special case when initialized } // Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() { // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) { return false; } // Special case when index == 0, just return b value if (index_ > 0) { // otherwise, calculate next sequence value previous_ += current_; } std::swap(current_, previous_); ++index_; return true; } // Get the current value in the sequence. unsigned long long fibonacci_current() { return current_; } // Get the current index position in the sequence. unsigned fibonacci_index() { return index_; }
En la ventana del editor, seleccione la pestaña para MathLibrary.cpp si ya está abierta. Si no es así, en el Explorador de soluciones, haga doble clic en MathLibrary.cpp en la carpeta Archivos de origen del proyecto MathLibrary para abrirlo.
En el editor, reemplace el contenido del
MathLibrary.cpparchivo por el código siguiente:// MathLibrary.cpp : Defines the exported functions for the DLL. #include "stdafx.h" // use pch.h in Visual Studio 2019 and later #include <utility> #include <limits.h> #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) { index_ = 0; current_ = a; previous_ = b; // see special case when initialized } // Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() { // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) { return false; } // Special case when index == 0, just return b value if (index_ > 0) { // otherwise, calculate next sequence value previous_ += current_; } std::swap(current_, previous_); ++index_; return true; } // Get the current value in the sequence. unsigned long long fibonacci_current() { return current_; } // Get the current index position in the sequence. unsigned fibonacci_index() { return index_; }
Para comprobar que todo funciona hasta ahora, compile el archivo DLL. Para compilar, elija Compilar>solución de compilación en la barra de menús. El archivo DLL y la salida del compilador relacionado se colocan en una carpeta denominada Debug directamente debajo de la carpeta de la solución. Si crea una compilación release, la salida se coloca en una carpeta denominada Release. El resultado deberá ser ahora similar a esto:
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>pch.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>stdafx.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>MathLibrary.cpp
1>dllmain.cpp
1>Generating Code...
1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.pdb (Partial PDB)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Enhorabuena, ha creado un archivo DLL con Visual Studio. A continuación, creará una aplicación cliente que use las funciones exportadas por el archivo DLL.
Creación de una aplicación cliente que use el archivo DLL
Al crear un archivo DLL, piense en cómo podrían usarlo las aplicaciones cliente. Para llamar a las funciones o acceder a los datos exportados por un archivo DLL, el código fuente del cliente debe tener las declaraciones disponibles en tiempo de compilación. En el momento del vínculo, el enlazador requiere información para resolver las llamadas de función o los accesos a datos. Un archivo DLL proporciona esta información en una biblioteca de importación, un archivo que contiene información sobre cómo buscar las funciones y los datos, en lugar del código real. Y en tiempo de ejecución, el archivo DLL debe estar disponible para el cliente, en una ubicación que el sistema operativo pueda encontrar.
Tanto si es propio como de un tercero, el proyecto de la aplicación cliente necesita varios fragmentos de información para usar un fichero DLL. Debe encontrar los encabezados que declaran las exportaciones dll, las bibliotecas de importación para el enlazador y el propio archivo DLL. Una solución consiste en copiar todos estos archivos en el proyecto de cliente. En el caso de archivos DLL de terceros que no es probable que cambien mientras el cliente está en desarrollo, este método podría ser la mejor manera de usarlos. Sin embargo, cuando también se compila el archivo DLL, es mejor evitar la duplicación. Si realiza una copia local de archivos DLL que están en desarrollo, es posible que cambie accidentalmente un archivo de encabezado en una copia, pero no en la otra, o use una biblioteca obsoleta.
Para evitar el código desincronizado, se recomienda establecer la ruta de inclusión en el proyecto cliente para incluir directamente los archivos de encabezado DLL desde su proyecto DLL. Además, establezca la ruta de acceso de biblioteca en el proyecto cliente para incluir las bibliotecas de importación de DLL desde el proyecto DLL. Y, por último, copie el archivo DLL compilado desde el proyecto DLL en el directorio de salida de compilación del cliente. Este paso permite que la aplicación cliente use el mismo código DLL que compile.
Para crear una aplicación cliente en Visual Studio
En la barra de menús, elija Archivo>nuevo>proyecto para abrir el cuadro de diálogo Crear un nuevo proyecto .
En la parte superior del cuadro de diálogo, establezca Lenguaje en C++, establezca Plataforma en Windows y Tipo de proyecto en Consola.
En la lista de plantillas de proyecto, seleccione Aplicación de consola y Siguiente.
En la página Configurar el nuevo proyecto , escriba MathClient en el cuadro Nombre del proyecto para especificar un nombre para el proyecto. Deje los valores predeterminados Ubicación y Nombre de la solución . Establezca Solución en Crear nueva solución. Desactive Colocar solución y proyecto en el mismo directorio si está activado.
Haga clic en el botón Crear para crear el proyecto de cliente.
Se crea un proyecto de aplicación de consola mínimo automáticamente. El nombre del archivo de origen principal es el mismo que el nombre del proyecto que especificó anteriormente. En este ejemplo, se denomina MathClient.cpp. Puede compilarlo, pero aún no usa el archivo DLL.
Para crear una aplicación cliente en Visual Studio 2017
Para crear una aplicación de C++ que use el archivo DLL que creó, en la barra de menús, elija Archivo>nuevo>proyecto.
En el panel izquierdo del cuadro de diálogo Nuevo proyecto , seleccione Escritorio de Windows en Instalado>Visual C++. En el panel central, seleccione Aplicación de consola de Windows. Especifique el nombre del proyecto, MathClient, en el cuadro de edición Nombre . Deje los valores predeterminados Ubicación y Nombre de la solución . Establezca Solución en Crear nueva solución. Marque Crear directorio para la solución si no está marcado.
Elija Aceptar para crear el proyecto de aplicación cliente.
Se ha creado un proyecto de aplicación de consola sencilla para ti. El nombre del archivo de origen principal es el mismo que el nombre del proyecto que especificó anteriormente. En este ejemplo, se denomina MathClient.cpp. Puede compilarlo, pero aún no usa el archivo DLL.
Para crear una aplicación cliente en Visual Studio 2015
Para crear una aplicación de C++ que use el archivo DLL que creó, en la barra de menús, elija Archivo>nuevo>proyecto.
En el panel izquierdo del cuadro de diálogo Nuevo proyecto, seleccione Win32 enPlantillas instaladas>>Visual C++. En el panel central, seleccione Aplicación de consola Win32. Especifique el nombre del proyecto, MathClient, en el cuadro de edición Nombre . Deje los valores predeterminados Ubicación y Nombre de la solución . Establezca Solución en Crear nueva solución. Marque Crear directorio para la solución si no está marcado.
Elija el botón Aceptar para descartar el cuadro de diálogo Nuevo proyecto e inicie el Asistente para aplicaciones Win32. En la página Información general del cuadro de diálogo Asistente para aplicaciones Win32 , elija el botón Siguiente .
En la página Configuración de la aplicación , en Tipo de aplicación, seleccione Aplicación de consola si aún no está seleccionada.
Elija el botón Finalizar para crear el proyecto.
Cuando el asistente finalice, se creará automáticamente un proyecto mínimo de aplicación de consola. El nombre del archivo de origen principal es el mismo que el nombre del proyecto que especificó anteriormente. En este ejemplo, se denomina MathClient.cpp. Puede compilarlo, pero aún no usa el archivo DLL.
A continuación, para llamar a las funciones MathLibrary en el código fuente, el proyecto debe incluir el MathLibrary.h archivo. Puede copiar este archivo de encabezado en el proyecto de aplicación cliente y, a continuación, agregarlo al proyecto como un elemento existente. Este método puede ser una buena opción para las bibliotecas de terceros. Sin embargo, si está trabajando en el código para el archivo DLL y el cliente al mismo tiempo, los archivos de encabezado podrían salir de la sincronización. Para evitar este problema, establezca la ruta de acceso Directorios de inclusión adicionales del proyecto para incluir la ruta de acceso al encabezado original.
Para agregar el encabezado de la DLL a la ruta de inclusión
Haga clic con el botón derecho en el nodo MathClient del Explorador de soluciones para abrir el cuadro de diálogo Páginas de propiedades .
En el cuadro desplegable Configuración , seleccione Todas las configuraciones si aún no está seleccionada.
En el panel izquierdo, seleccione Propiedades> de configuraciónC/C++>General.
En el panel de propiedades, seleccione el control desplegable situado junto al cuadro de edición Directorios de inclusión adicionales y, a continuación, elija Editar.
Haga doble clic en el panel superior del cuadro de diálogo Directorios de inclusión adicionales para habilitar un control de edición. O bien, elija el icono de carpeta para crear una nueva entrada.
En el control de edición, especifique la ruta de acceso a la ubicación del
MathLibrary.harchivo de encabezado. Puede elegir el control de puntos suspensivos (...) para ir a la carpeta correcta.También puede introducir una ruta de acceso relativa desde los archivos de origen del cliente a la carpeta que contiene los archivos de encabezado DLL. Si siguió las instrucciones para colocar el proyecto de cliente en una solución separada del archivo DLL, la ruta relativa debería verse así:
..\..\MathLibrary\MathLibrarySi los proyectos DLL y cliente están en la misma solución, la ruta de acceso relativa podría tener este aspecto:
..\MathLibraryCuando los proyectos dll y cliente están en otras carpetas, ajuste la ruta de acceso relativa para que coincida. O bien, use el control de puntos suspensivos para buscar la carpeta.
Después de escribir la ruta de acceso al archivo de encabezado en el cuadro de diálogo Directorios de inclusión adicionales , elija el botón Aceptar . En el cuadro de diálogo Páginas de propiedades, elija el botón Aceptar para guardar los cambios.
Ahora puede incluir el MathLibrary.h archivo y usar las funciones que declara en la aplicación cliente. Reemplace el contenido de MathClient.cpp mediante este código:
// MathClient.cpp : Client app for MathLibrary DLL.
// #include "pch.h" Uncomment for Visual Studio 2017 and earlier
#include <iostream>
#include "MathLibrary.h"
int main()
{
// Initialize a Fibonacci relation sequence.
fibonacci_init(1, 1);
// Write out the sequence values until overflow.
do {
std::cout << fibonacci_index() << ": "
<< fibonacci_current() << std::endl;
} while (fibonacci_next());
// Report count of values written before overflow.
std::cout << fibonacci_index() + 1 <<
" Fibonacci sequence values fit in an " <<
"unsigned 64-bit integer." << std::endl;
}
Este código se puede compilar, pero no vincular. Si compila la aplicación cliente ahora, la lista de errores muestra varios errores LNK2019. Esto se debe a que el proyecto no tiene información: aún no ha especificado que el proyecto tiene una dependencia en la MathLibrary.lib biblioteca. Y no le ha dicho al enlazador cómo encontrar el MathLibrary.lib archivo.
Para corregir este problema, podría copiar el archivo de biblioteca directamente en el proyecto de aplicación cliente. El enlazador lo encontraría y lo usaría automáticamente. Sin embargo, si la biblioteca y la aplicación cliente están en desarrollo, esto podría dar lugar a cambios en una copia que no se muestran en la otra. Para evitar este problema, puede establecer la propiedad Dependencias adicionales para indicar al sistema de compilación que el proyecto depende de MathLibrary.lib. Además, puede establecer una ruta de acceso Directorios de Biblioteca Adicionales en su proyecto para incluir la ruta a la biblioteca original cuando vincule.
Para agregar la biblioteca de importación de DLL al proyecto
Haga clic con el botón derecho en el nodo MathClient en el Explorador de soluciones y elija Propiedades para abrir el cuadro de diálogo Páginas de propiedades .
En el cuadro desplegable Configuración , seleccione Todas las configuraciones si aún no está seleccionada. Garantiza que los cambios de propiedad se apliquen a las compilaciones Debug y Release.
En el panel izquierdo, seleccione Propiedades de configuración>Enlazador>Entrada. En el panel de propiedades, seleccione el control desplegable situado junto al cuadro de edición Dependencias adicionales y, a continuación, elija Editar.
En el cuadro de diálogo Dependencias adicionales , agregue
MathLibrary.liba la lista en el control de edición superior.
Elija Aceptar para volver al cuadro de diálogo Páginas de propiedades .
En el panel izquierdo, seleccione Propiedades de> configuraciónVinculador>General. En el panel de propiedades, seleccione el control desplegable situado junto al cuadro de edición Directorios de biblioteca adicionales y, a continuación, elija Editar.
Haga doble clic en el panel superior del cuadro de diálogo Directorios de biblioteca adicionales para habilitar un control de edición. En el control de edición, especifique la ruta de acceso a la ubicación del
MathLibrary.libarchivo. De forma predeterminada, se encuentra en una carpeta denominada Depurar directamente en la carpeta de la solución DLL. Si crea una compilación de versión de lanzamiento, el archivo se coloca en la carpeta denominada Release. Puede usar la$(IntDir)macro para que el enlazador pueda encontrar el archivo DLL, independientemente del tipo de compilación que cree. Si ha seguido las instrucciones para colocar el proyecto de cliente en una solución independiente del proyecto DLL, la ruta de acceso relativa debe tener este aspecto:..\..\MathLibrary\$(IntDir)Si los proyectos DLL y Cliente están en otras ubicaciones, ajuste la ruta de acceso relativa para que se correspondan.
Una vez que haya escrito la ruta de acceso al archivo de biblioteca en el cuadro de diálogo Directorios de biblioteca adicionales , elija el botón Aceptar para volver al cuadro de diálogo Páginas de propiedades . Elija Aceptar para guardar los cambios de propiedad.
La aplicación cliente ahora puede compilar y vincularse correctamente, pero aún no tiene todo lo que necesita para ejecutarse. Cuando el sistema operativo carga la aplicación, busca el archivo DLL MathLibrary. Si no encuentra el archivo DLL en determinados directorios del sistema, la ruta de acceso del entorno o el directorio de la aplicación local, se produce un error en la carga. En función del sistema operativo, verá un mensaje de error similar al siguiente:
Una manera de evitar este problema es copiar el archivo DLL en el directorio que contiene el ejecutable del cliente como parte del proceso de compilación. Puede agregar un evento posterior a la compilación al proyecto para agregar un comando que copie el archivo DLL en el directorio de salida de compilación. El comando especificado aquí copia el archivo DLL solo si falta o ha cambiado. Usa macros para copiar hacia y desde las ubicaciones de depuración o liberación, en función de la configuración de compilación.
Para copiar el archivo DLL en un evento posterior a la compilación
Haga clic con el botón derecho en el nodo MathClient en el Explorador de soluciones y elija Propiedades para abrir el cuadro de diálogo Páginas de propiedades .
En el cuadro desplegable Configuración , seleccione Todas las configuraciones si aún no está seleccionada.
En el panel izquierdo, seleccione Propiedades de configuración>Eventos de compilación>Evento posterior a la compilación.
En el panel de propiedades, seleccione el control de edición en el campo Línea de comandos . Si ha seguido las instrucciones para colocar el proyecto de cliente en una solución independiente del proyecto DLL, escriba este comando:
xcopy /y /d "..\..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)"Si sus proyectos DLL y de cliente están en otros directorios, cambie la ruta de acceso relativa al archivo DLL para que sea acorde.
Elija el botón Aceptar para guardar los cambios en las propiedades del proyecto.
Ahora la aplicación cliente tiene todo lo que necesita para compilar y ejecutar. Compile la aplicación seleccionando Compilar>solución de compilación en la barra de menús. La ventana Salida de Visual Studio debe tener algo parecido al ejemplo siguiente en función de la versión de Visual Studio:
1>------ Build started: Project: MathClient, Configuration: Debug Win32 ------
1>MathClient.cpp
1>MathClient.vcxproj -> C:\Users\username\Source\Repos\MathClient\Debug\MathClient.exe
1>1 File(s) copied
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Enhorabuena, ha creado una aplicación que llama a funciones en el archivo DLL. Ahora ejecute la aplicación para ver lo que hace. En la barra de menús, elija Depurar>Iniciar sin depurar. Visual Studio abre una ventana de comandos para que el programa se ejecute. La última parte de la salida debe ser similar a la siguiente:
Presione cualquier tecla para descartar la ventana de comandos.
Ahora que ha creado un archivo DLL y una aplicación cliente, puede experimentar. Pruebe a establecer puntos de interrupción en el código de la aplicación cliente y ejecute la aplicación en el depurador. Vea lo que sucede cuando se realiza una llamada de biblioteca. Agregue otras funciones a la biblioteca o escriba otra aplicación cliente que use el archivo DLL.
Al implementar la aplicación, también debe implementar los archivos DLL que usa. La manera más sencilla de hacer que los archivos DLL que compile, o que incluya de terceros, estén disponibles es colocarlos en el mismo directorio que la aplicación. Se conoce como implementación local de la aplicación. Para obtener más información sobre la implementación, vea Implementación en Microsoft C++.