[ACCEPTED]-DllImport vs Declare in VB.NET-declare

Accepted answer
Score: 21

Apparently the Declare and DllImport statements 80 are basically the same. You can use whichever 79 you prefer.

Following is a discussion of 78 the few points that may work a little differently 77 in each, which may influence a preference 76 for one over the other:

I started with an 75 article from MSDN regarding Visual Studio 74 2003 titled Using the DllImport Attribute. (A bit old, but since the 73 DllImport statement seems to have originated 72 in .NET, it seemed appropriate to go back 71 to the beginning.)

Given an example DllImport 70 statement of:

[DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]
int MessageBox(void* hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned int uType);

It says that if the EntryPoint 69 value is left out, the CLR will look for the 68 name of the function (MessageBox, in this 67 case) as a default. However, in this instance, since 66 a CharSet of Unicode was specified, the 65 CLR would FIRST look for a function called 64 "MessageBoxW" - the 'W' indicating 63 a Unicode return type. (The ANSI return 62 type version would be "MessageBoxA".) If 61 no "MessageBoxW" were found, THEN 60 the CLR would look for an API function actually 59 called "MessageBox".

Current specifics 58 about the DllImportAttribute class can be 57 found here, where I viewed the .NET Framework 56 4 version: DLLImportAttribute Class

A key comment in the Remarks 55 section of this .NET Framework 4 page is 54 that:

You apply this attribute directly to 53 C# and C++ method definitions; however, the 52 Visual Basic compiler emits this attribute 51 when you use the Declare statement.

So, at 50 least as pertains to VB.NET, the compiler 49 ends up with a Declare statement anyway.

There is 48 also an important note in this page:

The 47 DllImportAttribute does not support marshaling 46 of generic types.

So, it would appear that 45 if you want to use a generic type, you'd 44 have to use a Declare statement.

Next, I headed 43 to the Declare statement information. A 42 Visual Studio 2010 version (Visual Basic 41 statement info) was here: Declare Statement

A key item here 40 was this note:

You can use Declare only at 39 module level. This means the declaration 38 context for an external reference must be 37 a class, structure, or module, and cannot 36 be a source file, namespace, interface, procedure, or 35 block.

Apparently, if you want to set up 34 an API call outside of a class, structure, or 33 module, you'll have to use the DllImport 32 statement instead of the Declare.

The example Declare statement 31 on this page is:

Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" (
  ByVal lpBuffer As String, ByRef nSize As Integer) As Integer

Following that example is 30 this little tidbit of information:

The DllImportAttribute 29 provides an alternative way of using functions 28 in unmanaged code. The following example 27 declares an imported function without using 26 a Declare statement.

followed by, of course, an 25 example of DllImport usage.

Regarding Unicode 24 vs ANSI results, according to this Declare 23 page, if you specify a CharSet value (available 22 in Declare, but not shown in the example 21 above) the CLR will do the same type of 20 automatic name search that DllImport does 19 - for either Unicode or ANSI.

If you do not 18 specify a CharSet value in the Declare statement, then 17 you must make sure that your function name 16 in the Declare is the same as the function 15 name in the actual API function's header 14 file, OR you must specifiy an Alias value that 13 matches the actual function name in the 12 header file (as shown in the example above).

I 11 was not able to find any specific Microsoft 10 documentation stating that either DllImport 9 or Declare were preferred, or even recommended, over 8 one another in any situation other than 7 those noted above.

My conclusion, therefore, is:

1) Unless 6 you need to place your definition in one 5 of the places a Declare statement cannot be used, either 4 technique will work fine,

and

2) if you're 3 using DllImport, make sure you specify the 2 CharSet value you want (Unicode or ANSI), or 1 you may get unexpected results.

Score: 13

Declare is really an attempt to maintain 16 a P/Invoke syntax which would be more familiar to 15 Visual Basic 6.0 users converting to VB.NET. It 14 has many of the same features as P/Invoke 13 but the marshalling of certain types, in 12 particular strings, are very different and 11 can cause a bit of confusion to people more 10 familiar with DllImport rules.

I'm not 9 entirely sure what the documentation is 8 alluding to with the "rare" distinction. I 7 use DllImport in my code frequently from 6 both VB.NET and C# without issue.

In general, I 5 would use DllImport over Declare unless 4 you come from a Visual Basic 6.0 background. The 3 documentation and samples for DllImport 2 are much better and there are many tools 1 aimed at generating DllImport declarations.

Score: 8

In my opinion, since this keyword doesn't 15 look deprected, etc. from what I searched, simply 14 use compile-time keywords rather than attributes.

Also, when 13 you use the Declare, you don't need to write the 12 End Function. The advantage of that is that you can 11 create a whole module of declarations of 10 function imports line by line, with no need 9 to pulute your code with DllImports and End Functions.

When you 8 declare using the Declare keyword, the compiler 7 treats this function as Shared anyway, so it can 6 be accessed via other extenal objects.

But 5 I think in the current VB.NET they're both 4 addressed to the same target and no performance 3 difference - no warranty on this one.

So my conclusion is: Do use the Declare instead of DllImport, especially 2 reading what you quoted that Microsoft stated that it should 1 be used in rare cases.

Score: 1

If you need to set one of the following 17 options, then use DllImportAttribute attribute, else use Declare. From 16 https://msdn.microsoft.com/en-us/library/w4byd5y4.aspx

To apply the BestFitMapping, CallingConvention, ExactSpelling, PreserveSig, SetLastError, or 15 ThrowOnUnmappableChar fields to a Microsoft 14 Visual Basic 2005 declaration, you must 13 use the DllImportAttribute attribute instead 12 of the Declare statement.

It is unclear from 11 the above reference only whether this applies 10 to only "Visual Basic 2005" or 9 not, as the above reference is from a .NET 8 4.5 article. However, I also found this 7 article (https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute(v=vs.110).aspx ) which is specific to the DllImportAttribute class 6 in .NET 4.5 :

the Visual Basic compiler 5 emits this attribute when you use the Declare 4 statement. For complex method definitions that include BestFitMapping, CallingConvention, ExactSpelling, PreserveSig, SetLastError, or ThrowOnUnmappableChar fields, you apply this attribute directly to Visual Basic method definitions.

This tells you that the Declare option 3 is VB.net syntactical sugar which is converted 2 to DllImportAttribute at compile time, and outlines the exact 1 scenarios when using DllImportAttribute directly is recommended.

More Related questions