Using dllimport to call a function in. net
Yan jinxiong
JingxiongYan@hotmail.com
In the. NET development environment, if we need to call functions in other non-libraries, we need to use the dllimportattribute attribute which is defined in msdn as follows:
You can apply this attribute to methods.
The dllimportattribute provides the information needed to call a function exported from an unmanaged DLL. As a minimum requirement, you must supply the name of the DLL containing the entry point.
You apply this attribute directly to C # And C ++ method definitions; however, the Visual Basic compiler emits this attribute when you use the declare 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 attribute can be applied to methods. The dllimportattribute provides the required information for calling a function exported from an unmanaged DLL. as the minimum requirement, the name of the DLL containing the entry point must be provided. In addition, msdn provides us with a specific example. In CSHARP, we use dllimport to call the MessageBox method in the user32.dll library.
First, let's take a look at how the MessageBox method is defined in the Windows xp pro SP3 SDK.
/*
* MessageBox () flags
*/
# Define mb_ OK 0x00000000l
# Define mb_okcancel 0x00000001l
# Define mb_abortretryignore 0x00000002l
# Define mb_yesnocancel 0x00000003l
# Define mb_yesno 0x00000004l
# Define mb_retrycancel 0x00000005l
# If (winver> = 0x0500)
# Define mb_canceltrycontinue 0x00000006l
# Endif/* winver> = 0x0500 */
# Define mb_iconhand 0x00000010l
# Define mb_iconquestion 0x00000020l
# Define mb_iconexclamation 0x00000030l
# Define mb_iconasterisk 0x00000040l
# If (winver> = 0x0400)
# Define mb_usericon 0x00000080l
# Define mb_iconwarning mb_iconexclamation
# Define mb_iconerror mb_iconhand
# Endif/* winver> = 0x0400 */
# Define mb_iconinformation mb_iconasterisk
# Define mb_iconstop mb_iconhand
# Define mb_defbutton1 0x00000000l
# Define mb_defbutton2 0x00000100l
# Define mb_defbutton3 0x00000200l
# If (winver> = 0x0400)
# Define mb_defbutton4 0x00000300l
# Endif/* winver> = 0x0400 */
# Define mb_applmodal 0x00000000l
# Define mb_systemmodal 0x00001000l
# Define mb_taskmodal 0x00002000l
# If (winver> = 0x0400)
# Define mb_help 0x00004000l // HELP button
# Endif/* winver> = 0x0400 */
# Define mb_nofocus 0x00008000l
# Define mb_setforeground 0x0000000l
# Define mb_default_shorttop_only 0x00020000l
# If (winver> = 0x0400)
# Define mb_topmost 0x00040000l
# Define mb_right 0x00080000l
# Define mb_rtlreading 0x00100000l
# Endif/* winver> = 0x0400 */
# Ifdef _ win32_winnt
# If (_ win32_winnt> = 0x0400)
# Define mb_service_notification 0x00200000l
# Else
# Define mb_service_notification 0x00040000l
# Endif
# Define mb_service_icationication_nt3x 0x00040000l
# Endif
# Define mb_typemask 0x0000000fl
# Define mb_iconmask 0x000000f0l
# Define mb_defmask 0x00000f00l
# Define mb_modemask 0x00003000l
# Define mb_miscmask 0x0000c000l
Winuserapi
Int
Winapi
Messageboxa (
_ In_opt hwnd,
_ In_opt lpcstr lptext,
_ In_opt maid,
_ In uint utype );
Winuserapi
Int
Winapi
Messageboxw (
_ In_opt hwnd,
_ In_opt lpcwstr lptext,
_ In_opt maid,
_ In uint utype );
# Ifdef Unicode
# Define MessageBox messageboxw
# Else
# Define MessageBox messageboxa
# Endif //! Unicode
# If defined (_ m_cee)
# UNDEF MessageBox
_ Inline
Int
MessageBox (
Hwnd,
Lpctstr lptext,
Maid,
Uint utype
)
{
# Ifdef Unicode
Return messageboxw (
# Else
Return messageboxa (
# Endif
Hwnd,
Lptext,
Lpcaption,
Utype
);
}
# Endif/* _ m_cee */
It can be seen that MessageBox has four parameters. We only need to apply them according to the type defined by MessageBox.
Using system;
Using system. runtime. interopservices;
Class Example
{
// Use dllimport to import the Win32 MessageBox function.
[Dllimport ("user32.dll", charset = charset. Unicode)]
Public static extern int MessageBox (intptr hwnd, string text, string caption, uint type );
Static void main ()
{
// Call the MessageBox function using platform invoke.
MessageBox (New intptr (0), "Hello world! "," Hello dialog ", 0 );
}
}
How is it? Isn't it easy? It's clear about the principle. Now we can write a dllimportattribute application by ourselves. The function required by this program is to add a user account to the system, in general, we can use the netuseradd and netlocalgroupadd functions in netapi32.dll to complete specific operations. First, let's take a look at the prototype of the two functions.
Net_api_status net_api_function
Netuseradd (
In maid,
In DWORD level,
In lpbyte Buf,
Out lpdword parm_err optional
);
/*
................................
Omit irrelevant content
*/
Typedef struct _ user_info_1 {
Lpwstr usri1_name;
Lpwstr usri#password;
DWORD usri#password_age;
DWORD usri1_priv;
Lpwstr usri1_home_dir;
Lpwstr usrisponcomment;
DWORD usri1_flags;
Lpwstr usri1_script_path;
} User_info_1, * puser_info_1, * lpuser_info_1;
Net_api_status net_api_function
Netlocalgroupadd (
In maid,
In DWORD level,
In lpbyte Buf,
Out lpdword parm_err optional
);
Typedef struct _ localgroup_info_1 {
Lpwstr lgrpi1_name;
Lpwstr lgrpi1_comment;
} Localgroup_info_1, * plocalgroup_info_1, * lplocalgroup_info_1;
Now we have figured out its specific structure. Now we can develop an application by ourselves. The specific code in CSHARP is as follows:
Using system. runtime. interopservices;
Using Microsoft. Win32;
Using system;
// Author: Yan jinxiong
Namespace task
{
Class adduserapplication
{
[Dllimport ("netapi32.dll")]
Extern static int netuseradd ([financialas (unmanagedtype. lptstr)] string servername, int level, ref user_info_1 Buf, int parm_err );
[Dllimport ("netapi32.dll")]
Extern static int netlocalgroupadd ([financialas (unmanagedtype. lptstr)] string servername, int level, ref localgroup_info_1 Buf, int parm_err );
[Structlayout (layoutkind. Sequential, charset = charset. Unicode)]
Public struct user_info_1
{
Public String user_information_1_name;
Public String user_information_1_password;
Public String user_information_1_password_age;
Public int user_information_1_priv;
Public String user_information_1_home_dir;
Public String comment;
Public int user_information_1_flags;
Public String user_information_1_script_path;
}
Public struct localgroup_info_1
{
[Financialas (unmanagedtype. lpwstr)] Public String add_localgroup_1_name;
[Financialas (unmanagedtype. lpwstr)] Public String add_localgroup_comment comment;
}
Public static void main ()
{
If (add_a_user_account () = false)
{
Console. Write ("error: Adding User Failed sorry ");
}
Else
Add_a_useraccount_to_localgroup ();
}
// Public static void usage ()
//{
// Console. Write ("------------------------------------");
// Console. Write ("code by delphiscn ");
// Console. Write ("Email: Delphiscn@gmail.com ");
// Console. Write ("blog: http://blog.csdn.net/delphiscn ");
// Console. Write ("------------------------------------");
//}
Public static Boolean add_a_user_account ()
{
User_info_1 adduser = new user_info_1 ();
Adduser. user_information_1_name = "delphiscn ";
Adduser. user_information_1_password = "eviloctal ";
Adduser. user_information_1_priv = 1;
Adduser. user_information_1_home_dir = NULL;
Adduser. Comment = "add a user named delphiscn ";
Adduser. user_information_1_script_path = NULL;
If (netuseradd (null, 1, ref adduser, 0 )! = 0)
{
Console. Write ("error: Adding User Failed ");
Return false;
}
Return true;
}
Public static void add_a_useraccount_to_localgroup ()
{
Localgroup_info_1 addtogroup = new localgroup_info_1 ();
Addtogroup. add_localgroup_1_name = "Administrators ";
Addtogroup. add_localgroup_comment comment = "add a user to the Administrators group ";
If (netlocalgroupadd (null, 1, ref addtogroup, 0 )! = 0)
{
Console. Write ("adding to the Administrators group failed ");
}
}
}
}
Pass the test in Windows xp pro SP3 vs 2008 SP1. net3.5 Environment