Aparentemente, las declaraciones Declare y DllImport son básicamente las mismas. Puede usar el que prefiera.
A continuación se presenta una discusión de los pocos puntos que pueden funcionar de manera diferente en cada uno, que pueden influir en la preferencia por uno sobre el otro:
Empecé con un artículo de MSDN en relación con Visual Studio 2003 titulado Using the DllImport Attribute. (Un poco viejo, pero dado que la declaración de DllImport parece haberse originado en .NET, parecía apropiado volver al principio.)
Con un ejemplo comunicado DllImport de:
[DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]
int MessageBox(void* hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned int uType);
Se dice que si el valor EntryPoint se deja fuera, el CLR buscará el nombre de la función (de mensaje, en este caso) como por defecto . Sin embargo, en este caso, dado que se especificó un CharSet de Unicode, el CLR buscaría PRIMERO una función llamada "MessageBoxW" - la 'W' indica un tipo de retorno Unicode. (La versión del tipo de retorno ANSI sería "MessageBoxA".) Si no se encontrara "MessageBoxW", ENTONCES el CLR buscaría una función API realmente llamada "MessageBox".
detalles actuales acerca de la clase DllImportAttribute se pueden encontrar aquí, donde vi la versión de .NET Framework 4: DLLImportAttribute Class
Un comentario clave en la sección Comentarios de este .NET Framework 4 es la página que:
Aplica este atributo directamente a las definiciones de métodos C# y C++; sin embargo, el compilador de Visual Basic emite este atributo cuando usa la instrucción Declare.
Por lo tanto, al menos en lo que respecta a VB.NET, el compilador termina con una declaración Declare
de todos modos.
También hay una nota importante en esta página:
El DllImportAttribute no admite el cálculo de referencias de tipos genéricos.
Por lo tanto, parece que si desea utilizar un tipo genérico, tendría que utilizar una declaración Declare
.
A continuación, me dirigí a la información de declaración Declare. Una versión de Visual Studio 2010 (Visual información instrucción básica) era aquí: Declare Statement
Un elemento clave en este caso era esta nota:
Puede utilizar Declarar sólo a nivel de módulo. Esto significa que el contexto de declaración para una referencia externa debe ser una clase, estructura o módulo, y no puede ser un archivo fuente, espacio de nombres, interfaz, procedimiento o bloque.
Al parecer, si desea establecer una llamada a la API fuera de una clase, estructura o módulo, que tendrá que utilizar la instrucción DllImport en lugar de la Declare
.
El ejemplo Declare
declaración de esta página es:
Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" (
ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Siguiendo ese ejemplo es esta golosina poco de información:
El DllImportAttribute proporciona una forma alternativa de uso de funciones en código no administrado. El siguiente ejemplo declara una función importada sin usar una declaración Declare.
seguidos, por supuesto, de un ejemplo del uso de DllImport.
Respecto a los resultados Unicode vs ANSI, según esta página Declare, si especifica un valor CharSet (disponible en Declare, pero no en el ejemplo anterior) CLR hará el mismo tipo de búsqueda automática que DllImport - para Unicode o ANSI.
Si no se especifica un valor CharSet en la declaración Declare
, entonces debe asegurarse de que su nombre de función en la declare es el mismo que el nombre de la función en el archivo de cabecera de la función API actual, o debe specifiy un Alias
valor que coincide con el nombre de la función real en el archivo de encabezado (como se muestra en el ejemplo anterior).
No pude encontrar ninguna documentación específica de Microsoft que indique que DllImport o Declare fueron preferidos, o incluso recomendados, entre sí en cualquier situación que no sean las mencionadas anteriormente.
Mi conclusión, por tanto, es:
1) A menos que se han de fijar su definición en uno de los lugares una declaración Declare
no se puede utilizar, ya sea técnica funcionará bien,
y
2) si está utilizando DllImport, asegúrese de especificar el valor CharSet que desea (Unicode o ANSI), o puede obtener resultados inesperados.
Este es un gran artículo escrito y una gran investigación. ¡Muchas gracias! – Mike