[C #/C ++] C # Call the APIs of an unmanaged DLL

Source: Internet
Author: User
A lot of people are asking this question when I access Baidu or Google it. Recently I also used this, so I stayed for future support. I want to use this as the starting point for C # To call windows APIs. In the future, I will introduce some of the APIS or unmanaged class libraries I currently use. Before calling the APIs of an unmanaged DLL, we should have a good grasp of the dllimportattribute, which is defined by msdn as: This attribute can be applied to methods. The dllimportattribute is required to call a function exported from an unmanaged DLL. Information . As the minimum requirement, the name of the DLL containing the entry point must be provided.

1 [Dllimport ( " Kernel32.dll " , Entrypoint = " Movefilew " , Setlasterror = True ,
2
3 Charset = Charset. Unicode, exactspelling = True ,
4
5 Callingconvention = Callingconvention. stdcall)]
6
7 Public   Static   Extern   Bool Movefile (string SRC, string DST );
8
9

From the above example, we can see that this API is introduced from kernel32.dll, where entrypoint indicates the entry point, that is, the function name in the DLL. In fact, anyone who has used VC ++ knows that Windows APIs provides two versions, W and A, which are ANSI and Unicode. Currently, W is generally used, unicode programming,. net and Win32, charset is used by default. ANSI.
When the dllimportattribute. exactspelling field is set to true (it is the default value in Visual Basic. Net), only the name you specified is searched for Platform calls. For example, if MessageBox is specified, the platform call will search for MessageBox. If it cannot find the exact same spelling, it will fail.
When the exactspelling field is false (it is the default value in C ++ managed extension and C #), the platform call will first search for unprocessed aliases (MessageBox ), if no unprocessed alias is found, the processed name (messageboxa) is searched ).

Because many parameters are different from those in C #, let's see how the parameters are:

Extern "C" _ declspec (dllexport) int winapi sumab (int A, int B), which is of the same value type as C, changes in A and B will not affect the parameters in C. Expressed: 1 [Dllimport ("cppdll. dll " )]
2 // Int type
3 Public   Static   Extern   Int Sumab ( Int A1, Int B1 );

The following is the reference type: that is to say, the changes of A and B directly affect the values of A1 and B1. Public   Static   Extern   Int Sum ( Ref   Int A1, Ref   Int B1 );
// DLL statement
Extern "C" _ declspec (dllexport) Int Winapi sum ( Int   * A, Int   * B)

Similarly, we can obtain several value passing methods: the change of the first parameter does not affect the change of parameters in C #, And the char * type needs to be input. [Dllimport ("cppdll. dll " )]
// Input value
Public   Static   Extern   Int Together ( String Astr, String BSTR );
// DLL statement
Extern "C" _ declspec (dllexport) Int Winapi together ( Char   * Stra, Char   * Strb)

When the char * type needs to be transferred from the parameter, stringbuilder will be used. 1 // Outgoing Value
2 Public   Static   Extern   Int Getparameter (stringbuilder SB1, stringbuilder sb2 );
3 // DLL statement
4 Extern "C" _ declspec (dllexport) Int Winapi getparameter ( Char   * Stra, Char   * Strb)


Next, let's take a look at the structure of the mail, here we want to look at the structlayoutattribute label, through which you can define your own formatting type, in the hostingCodeThe formatting type is a structure or class member described by structlayoutattribute. It ensures the expected layout information of its internal members. Its member description is as follows:

Layoutkind. Automatic
To improve efficiency, the running state can be reordered by type members.
Note: never use this option to call an unmanaged Dynamic Linked Library function.

Layoutkind. Explicit
Sort type members by fieldoffset attribute for each domain

Layoutkind. Sequential
Sort the type members in the unmanaged memory where the managed type is defined.

You can use getsysteminfo to obtain system information. The Code is as follows:

1 Using System. runtime. interopservices;
2 [Structlayout (layoutkind. Sequential)]
3 Public   Struct System_info {
4 Public   Uint Dwoemid;
5 Public   Uint Dwpagesize;
6 Public   Uint Lpminimumapplicationaddress;
7 Public   Uint Lpmaximumapplicationaddress;
8 Public   Uint Dwactiveprocessormask;
9 Public   Uint Dwnumberofprocessors;
10 Public   Uint Dwprocessortype;
11 Public   Uint Dwallocationgranularity;
12 Public   Uint Dwprocessorlevel;
13 Public   Uint Dwprocessorrevision;
14 }
15 // Call
16 [Dllimport ( " Kernel32 " )]
17 Static   Extern   Void Getsysteminfo ( Ref System_info psi );
18 System_info PSI =   New System_info ();
19 Getsysteminfo ( Ref PSI );

When we encounter a function pointer parameter, we need to consider whether to use the callback function, such as enumerating all windows.

Bool enumwindows (wndenumproc lpenumfunc, lparmam iparam)

We can create a proxy with two parameters hwnd and lparam. The first parameter is a window handle, and the second parameter isProgramDefine. Both parameters are integer. When this callback function returns a non-zero value, it indicates that the execution is successful, and zero indicates that the operation fails. In this example, the value true is always returned for continuous enumeration.
Finally, create a proxy object (delegate) and pass it as a parameter to the enumwindows function. The platform automatically converts the proxy object into a callback format that can be recognized by the function.

1 Using System;
2 Using System. runtime. interopservices;
3 Public   Delegate   Bool Callback ( Int Hwnd, Int Lparam );
4 Public   Class Enumreportapp {
5 [Dllimport ( " USER32 " )]
6 Public   Static   Extern   Int Enumwindows (callback X, Int Y );
7 Public   Static   Void Main ()
8 {
9 Callback mycallback =   New Callback (enumreportapp. Report );
10 Enumwindows (mycallback, 0 );
11 }
12 Public   Static   Bool Report ( Int Hwnd, Int Lparam ){
13 Console. Write ( " The window handle is " );
14 Console. writeline (hwnd );
15 Return   True ;
16 }
17 }

OK, if you are familiar with the above aspects, basically can also call APIs don't forget P/invoke can help a lot, we can go to the Wiki website to query our desired API: http://pinvoke.net. It must be noted that many examples are retrieved from msdn and the Internet !!!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.