Modificaciones de cirugía plástica

Primero, el método externo debe declararse en el programa fuente del lenguaje C#. Su forma básica es: [[DLLImport("archivo DLL")] El modificador extern devuelve el nombre del método (lista de parámetros) del tipo de variable, donde: Archivo DLL: un archivo de biblioteca que contiene métodos externos. Modificador: modificador de acceso, que se puede utilizar al declarar métodos distintos de los abstractos. Tipo de variable de retorno: en el archivo DLL, se debe llamar al tipo de variable de retorno del método. Nombre del método: el nombre del método que necesita llamar en el archivo DLL. Lista de parámetros: lista de métodos que deben llamarse en el archivo DLL. Nota: Se requiere sistema. El espacio de nombres Runtime.InteropServices en la declaración del programa. DllImport solo se puede colocar en declaraciones de métodos. El archivo DLL debe estar ubicado en el directorio actual del programa o en la ruta de consulta definida por el sistema (es decir, la ruta establecida en la variable de entorno del sistema Ruta). El tipo de variable de retorno, el nombre del método y la lista de parámetros deben ser coherentes con la definición en el archivo DLL. Para usar otros nombres de funciones, puede configurar el atributo EntryPoint, como: [dllimport ("user32.dll", punto de entrada = " messageboxa ")] static extern int msgbox (en thnd, stringmsg, stringcaption, int type); Atributo DllImportAttribute opcional: CharSet representa el juego de caracteres utilizado en el punto de entrada, como CharSet=CharSet. Ansi; SetLastError indica si el método conserva el "último error" de Win32, por ejemplo SetLastError = true; ExactSpelling indica si EntryPoint debe coincidir exactamente con la ortografía del punto de entrada indicado, por ejemplo ExactSpelling = false. ; PreserveSig indica si la firma del método debe conservarse o convertirse, por ejemplo: PreserveSig = true; CallingConvention indica la convención de llamada del punto de entrada, como: convención de llamada = convención de llamada Además, consulte. a otra información sobre "clasificación de datos" y el artículo "Calificación de números y escalares lógicos" [2]. Ejemplo de C#: 1. Inicie VS.NET y cree un nuevo proyecto con el nombre de proyecto "Tzb" y la plantilla "Aplicación de Windows". 2. Haga doble clic en el elemento Botón en el elemento de Windows Form en la caja de herramientas para agregar un botón al Formulario 1. 3. Cambie las propiedades del botón: el nombre es "B1", el texto es "Llame a DllImport para que aparezca el cuadro emergente", ajuste el botón B1 al tamaño apropiado y muévalo a la posición apropiada. 4. Haga doble clic en "Form1" en la vista de clases, abra la vista de código de "Form1.cs", ingrese "Usar el servicio system.runtime.interop en "Namespace Tzb". Importe el espacio de nombres. 5. Haga doble clic en "Form1 Vista "Botón B1. CS [Diseño]", declare el método "MsgBox" con las palabras clave estáticas y externas encima del método "B1_Click" y adjunte el atributo DllImport al método. Aquí vamos a utilizar "user32.dll".

[DllImport("user32.dll ", punto de entrada = " MessageBoxA ")]static extern int MsgBox(int ​​​​hWnd, string msg, string caption, int type

Luego agregue el siguiente código en el cuerpo del método "B1_Click" para llamar al método "MsgBox":

MsgBox(0, "¡Este es el cuadro emergente que aparece cuando se llama a DllImport!", "Desafío Cup", 0x 30); 6. Presione "F5" para ejecutar el programa, haga clic en el botón B1 y aparecerá el siguiente cuadro emergente: (2) Cargue dinámicamente y llame a la función no administrada en la DLL. Se explicó anteriormente cómo llamar a una función no administrada en DllImport, pero esta es una función global. Si una función no administrada en una DLL tiene una variable estática S, la variable estática S se incrementará automáticamente en 65438 cada vez que se llame a la función. Como resultado, cuando es necesario volver a contar, no se puede obtener el resultado deseado. A continuación se utilizarán ejemplos para ilustrar: la creación de 1. DLL 1) Inicie Visual c 6.0; 2) Cree un nuevo proyecto llamado "Biblioteca de vínculos dinámicos Win32" 3) Seleccione "Un proyecto Dll simple" en la interfaz de selección "tipo dll" 4) Abra Count.cpp y agregue lo siguiente; código:

//Función de exportación, use la llamada estándar "_stdcall" extern "c"_declspec(dll Export)int_stdcallcount(intinit); int_stdcallcount(intinit){//count función, use el parámetro init para inicializar la variable plástica estática S, agregue 1 a S y devuelva el valor static int S = inits; }

5) Presione "F7" para compilar y obtener Count.dll (en el directorio del proyecto en la carpeta de depuración). 2. Llame a la función de recuento 1 en DllImport para abrir el proyecto "Tzb" y agregar un botón al formulario "Form1". 2) Cambie las propiedades del botón: el nombre es "B2", el texto es "Llamar a la función de conteo en DllImport", ajuste el botón B1 al tamaño apropiado y muévalo a la posición apropiada. 3) Abra la vista de código de "Form1.cs" y declare el método "count" con las palabras clave static y extern para que tenga la implementación de la función count exportada desde Count.dll. El código es el siguiente:

[DllImport(" count . dll ")]static extern int count(int init);

4) En el archivo "Form1.cs[ [Diseño ]" vista Haga doble clic en el botón B2 y agregue el siguiente código en el cuerpo del método "B2_Click":

MessageBox. Show("Al llamar a la función de recuento en DllImport, el parámetro pasado es 0 y el resultado es "count(0). ToString(), "Challenge Cup"); Show("Llame a la función de conteo en DllImport, el parámetro pasado es 10, el resultado es: "count (10). tostring() "n¡¡¡El resultado no es el 11 esperado!!!", "Challenge Cup"); .

Show("¡¡¡El resultado muestra que llamar a la función n no administrada en DllImport es una función estática global!!!", "Challenge Cup" 5) Copie Count.dll a la carpeta binDebug del proyecto "Tzb", presione "F5". " para ejecutar el programa, haga clic en el botón B2 y aparecerán los siguientes tres cuadros de mensaje:

El cuadro de mensaje 1 muestra el resultado de llamar a "count(0)" y el segundo cuadro de mensaje muestra el resultado de llamar a "count(10)" El resultado demuestra que "la función no administrada llamada en DllImport es una función estática global". Entonces, a veces no podemos lograr el objetivo, por lo que necesitamos usar el siguiente método: C# llama dinámicamente a la función en la DLL. 3.C# llama dinámicamente funciones en DLL. Debido a que DllImport en C# no puede cargar/descargar ensamblados dinámicamente, solo puede usar funciones API. En kernel32.dll, las funciones relacionadas con las llamadas a la biblioteca dinámica son [3]: ① LoadLibrary (o AfxLoadLibrary de MFC), carga la biblioteca dinámica. ② GetProcAddress, obtenga la función que se introducirá y convierta el nombre del símbolo o el número de identificación en la dirección interna de la DLL. ③FreeLibrary (o AfxFreeLibrary de MFC), lanza la biblioteca de enlaces dinámicos. Sus prototipos son: biblioteca de carga Hmodule (lpctstr lpfilename); FARPROC GetProcAddress (HMODULE HMODULE, LPCWSTR lpProcName); biblioteca gratuita BOOL (HMODULE HMODULE) Ahora, podemos usar intptrhmodule = loadlibrary ("count. dll"); , utilice intptrfarproc = getprocaddress(hm odule, " _ count @ 4 ") para obtener la dirección de entrada de la función. Sin embargo, después de conocer la dirección de entrada de la función, ¿cómo llamar a esta función? Debido a que no hay punteros de función en C#, no existe un método de llamada de puntero de función como C#, por lo que tenemos que usar otros métodos. A través de la investigación, descubrimos que podemos lograr nuestros objetivos combinando clases y funciones en el sistema. Reflection.Emit y System.Reflection.Assembly Para facilitar el uso futuro y la reutilización del código, podemos escribir una clase. 1) escritura dld: 1. Abra el proyecto Tzb, abra la vista de clases, haga clic derecho en Tzb y seleccione Agregar-gt, el nombre de la clase se establece en "dld", que es la primera letra de cada palabra del dll cargado dinámicamente. 2. Agregue el espacio de nombres requerido y declare la enumeración para el método de paso de parámetros:

Usar system. Runtime.InteropServices//DllImport requiere el uso del espacio de nombres del sistema. Reflexión; //Usar sistema para usar este espacio de nombres. Reflection.Emit usa la clase ensambladora; //Este espacio de nombres es necesario para usar ILGenerator.

Agregue el siguiente código encima de "Clase pública dld" para declarar la enumeración del método de paso de parámetros:

/// lt; Resumen gt /// Método de paso de parámetros de enumeración, ByValue significa transferencia de valor, ByRef significa transferencia de dirección //

/// lt; resumen gt /// El prototipo es: Hmodule LoadLibrary(lpctstr lpfilename); lt; nombre del parámetro = " lpFileName " nombre del archivo gtDLL

/// lt; Resumen gt///Cargar DLL//

public Void LoadDLL(intptr HMODULE){ if(hm odule = = intptr . zero)throw(newException("El identificador hm odule del módulo de biblioteca de funciones pasado está vacío."); hModule = HMODULE} 5. Agregue el método LoadFun y sobrecarguelo para llamarlo fácilmente. El código específico y los comentarios del método son los siguientes:

///lt; resumengt////lt function pointer//

///lt; desinstalar DLL //