) C # Call functions in DLL

Source: Internet
Author: User
When you study C # In actual work, you may ask: why do we need to provide some existing functions (for example, some functions in windows, some methods that have been compiled in C ++) to rewrite Code , C # Is there a way to directly use these existing functions? The answer is yes. You can directly call these functions through dllimport in C.
The namespace using system. runtime. interopservices where dllimport is located;
The explanation of dllimportattribute in msdn is as follows: This attribute can be applied to methods. The dllimportattribute attribute provides the information necessary to call a function exported from an unmanaged DLL. As the minimum requirement, the name of the DLL containing the entry point must be provided .
The dllimport attribute is defined as follows:
Namespace system. runtime. interopservices
{
[Attributeusage (attributetargets. Method)]
Public class dllimportattribute: system. Attribute
{
Public dllimportattribute (string dllname ){...}
Public callingconvention;
Public charset;
Public String entrypoint;
Public bool exactspelling;
Public bool preservesig;
Public bool setlasterror;
Public String Value {get {...}}
}
}
Note:
1. dllimport can only be placed on method declaration.
2. dllimport has a single positioning parameter: Specify the dllname parameter that contains the DLL name of the imported method.
3. dllimport has five naming parameters:
A. The callingconvention parameter indicates the call convention of the entry point. If no callingconvention is specified, use the default value callingconvention. winapi.
B. The charset parameter indicates the character set used in the entry point. If charset is not specified, the default value charset. Auto is used.
C. The entrypoint parameter specifies the name of the DLL entry point. If entrypoint is not specified, the method name is used.
D. The exactspelling parameter indicates whether the entrypoint must exactly match the spelling of the indicated entry point. If exactspelling is not specified, use the default value false.
E. The preservesig parameter indicates whether the method signature should be retained or converted. When the signature is converted, it is converted to a signature with an additional output parameter named retval that has the hresult return value and the return value. If preservesig is not specified, the default value true is used.
The F and setlasterror parameters indicate whether the method retains Win32 "previous error ". If setlasterror is not specified, the default value false is used.
4. It is a one-time attribute class.
5. In addition, the method modified with the dllimport attribute must have an extern modifier.

Usage of dllimport:
Dllimport ("mydllimport. dll")]
Private Static extern int mysum (int A, int B );

I. in C #ProgramWin32 class library used in design
Common corresponding types:
1. DWORD is a 4-byte integer, so we can use Int or uint as the corresponding type of C.
2. the bool type corresponds to the bool type.

Example 1: Call BEEP () API to make a sound
Beep () is defined in kernel32.lib and defined in msdn. Beep has the following prototype:
Bool BEEP (DWORD dwfreq, // Audio Frequency
DWORD dwduration // sound duration );
Use C # To compile the following prototype:
[Dllimport ("kernel32.dll")]
Public static extern bool BEEP (INT frequency, int duration );

Example 2: Enumeration type and constant
Messagebeep () is defined in user32.lib. In msdn, messagebeep has the following prototype:
Bool messagebeep (uint utype // sound type
);

Use C # To compile the prototype:
Public Enum beeptype
{
Simplebeep =-1,
Iconasterisk = 0x00000040,
Iconexclamation = 0x00000030,
Iconhand = 0x00000010,
Iconquestion = 0x00000020,
OK = 0x00000000,
}
The utype parameter actually accepts a set of predefined constants. It is reasonable to use the enum type for the utype parameter.
[Dllimport ("user32.dll")]
Public static extern bool messagebeep (beeptype );

Example 3: Processing Structure
Sometimes I need to determine the battery condition of my laptop. Win32 provides a power management function. You can find the getsystempowerstatus () function by searching for msdn.
Bool getsystempowerstatus (
Lpsystem_power_status lpsystempowerstatus
);
This function contains a pointer to a structure that we have not processed. To process the structure, we need to use C # to define the structure. We start with the definition of unmanaged systems:
Typedef struct _ system_power_status {
Byte aclinestatus;
Byte batteryflag;
Byte batterylifepercent;
Byte reserved1;
DWORD batterylifetime;
DWORD batteryfulllifetime;
} System_power_status, * lpsystem_power_status;
Then, use the C # type instead of the C type to get the C # version.
Struct systempowerstatus
{
Byte aclinestatus;
Byte batteryflag;
Byte batterylifepercent;
Byte reserved1;
Int batterylifetime;
Int batteryfulllifetime;
}
In this way, you can easily compile the C # prototype:
[Dllimport ("kernel32.dll")]
Public static extern bool getsystempowerstatus (
Ref systempowerstatus );
In this prototype, we use "Ref" to specify that the structure pointer will be passed instead of the structure value. This is a general method for processing the structure passed through pointers.
This function works well, but it is best to define the aclinestatus and batteryflag fields as Enum:
Enum aclinestatus: byte
{
Offline = 0,
Online = 1,
Unknown = 255,
}
Enum batteryflag: byte
{
High = 1,
Low = 2,
Critical = 4,
Charging = 8,
Nosystembattery = 128,
Unknown = 255,
}
Note that because the fields in the structure are some bytes, we use byte as the basic type of The enum.

Example 4: Process strings

Call C ++ code in C #
Int type 
[Dllimport ("mydll. dll")]
// Return int type
Public static extern int mysum (INT A1, int B1 );
// Declare in DLL
Extern "C" _ declspec (dllexport) int winapi mysum (INT A2, int B2)
{
// A2 B2 cannot change A1 B1
// A2 = ..
// B2 =...
Return A + B;
}

// Input the int type.
Public static extern int mysum (ref int A1, ref int B1 );
// Declare in DLL
Extern "C" _ declspec (dllexport) int winapi mysum (int * A2, int * B2)
{
// Changes A1 and B1.
* A2 =...
* B2 =...
Return A + B;
}

The dll must be of the char * type.
[Dllimport ("mydll. dll")]
// Input value
Public static extern int mysum (string astr1, string bstr1 );
// Declare in DLL
Extern "C" _ declspec (dllexport) int winapi mysum (char * astr2, char * bstr2)
{
// Change astr2 BSTR 2, astr1 bstr1 will not be changed
Return A + B;
}

DLL needs to output char * type 
[Dllimport ("mydll. dll")]
// Outgoing Value
Public static extern int mysum (stringbuilder abuf, stringbuilder bbuf );
// Declare in DLL
Extern "C" _ declspec (dllexport) int winapi mysum (char * astr, char * BSTR)
{
// Output char * changes astr BSTR --> abuf, bbuf can be changed
Return A + B;
}
 
DLL callback function 

Bool enumwindows (wndenumproc lpenumfunc, lparam)

Using system;
Using system. runtime. interopservices;
Public Delegate bool callback (INT hwnd, int lparam); // defines the delegate Function Type
Public class enumreportapp
{
[Dllimport ("USER32")]
Public static extern int enumwindows (callback X, int y );
Public static void main (){
Callback mycallback = new callback (enumreportapp. Report); enumwindows (mycallback, 0 );
}
Public static bool report (INT hwnd, int lparam)
{
Console. Write ("window handle is ");
Console. writeline (hwnd); Return true;
}
}

DLL Transfer Structure
Bool ptinrect (const rect * LPRC, point pt );

using system. runtime. interopservices;
[structlayout (layoutkind. sequential)]
public struct point {
Public int X;
Public int y;
}< br> [structlayout (layoutkind. explicit)]
public struct rect
{< br> [fieldoffset (0)] public int left;
[fieldoffset (4)] public int top;
[fieldoffset (8)] public int right;
[fieldoffset (12)] public int bottom;
}< br> class XXXX {
[dllimport ("user32.dll")]
Public static extern bool ptinrect (ref rect R, point P );
}

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.