. The use of C # in DllImport in net

Source: Internet
Author: User

When you're actually working on C #, you might ask: Why do we have to rewrite the code for something that already exists, such as some of the features in Windows, some of which are already written in C + +, and is there a way for C # to use these already existing functions directly? The answer is yes, you can call these features directly from the DllImport in C #.
DllImport The name space using System.Runtime.InteropServices;
The explanation for DllImportAttribute in MSDN is this: You can apply this property to a method. The DllImportAttribute property provides the information necessary to invoke a function that is exported from an unmanaged DLL. As a minimum requirement, you must provide the name of the DLL that contains the entry point.
The DllImport property is defined as follows:
Namespace System.Runtime.InteropServices
{
[AttributeUsage (AttributeTargets.Method)]
public class DllImportAttribute:System.Attribute
{
Public DllImportAttribute (String dllName) {...}
Public CallingConvention callingconvention;
Public CharSet CharSet;
public string entrypoint;
public bool ExactSpelling;
public bool PreserveSig;
public bool SetLastError;
public string Value {get {...}}
}
}
Description
1, DllImport can only be placed on the method declaration.
2. DllImport has a single positional parameter: Specifies the DllName parameter that contains the DLL name of the imported method.
3. DllImport has five named parameters:
A, the CallingConvention parameter indicates the calling convention of the entry point. If CallingConvention is not specified, the default value of Callingconvention.winapi is used.
b, the CharSet parameter indicates the character set used in the entry point. If CharSet is not specified, the default value of CharSet.Auto is used.
The C, entrypoint parameter gives the name of the entry point in the DLL. If entrypoint is not specified, the name of the method itself is used.
The D, exactspelling parameter indicates whether the entrypoint must exactly match the spelling of the indicated entry point. If ExactSpelling is not specified, the default value of false is used.
E, the PreserveSig parameter indicates whether the signature of the method should be preserved or converted. When the signature is converted, it is converted to a signature of an additional output parameter named RetVal with the HRESULT return value and the return value. If PreserveSig is not specified, the default value of True is used.
The F, setlasterror parameter indicates whether the method retains Win32 "previous error". If SetLastError is not specified, the default value of false is used.
4, it is a one-time attribute class.
5. In addition, methods decorated with the DllImport attribute must have an extern modifier.

========================================================

DllImportis an attribute class under the System.Runtime.InteropServices namespace, and its function is to provide the necessary invocation information for functions exported from an unmanaged DLL.
The DllImport property is applied to a method, requiring a minimum of the name of the DLL that contains the entry point.
DllImportis defined as follows:
        




Public CharSet CharSet;
public string entrypoint;
public bool ExactSpelling;
public bool PreserveSig;
public bool SetLastError;

Usage examples:
    
private static extern long WritePrivateProfileString (string section,string key,string val,string filePath);

    above is a WIN32API used to write to the INI file.
    
    call Win32API in this manner corresponds to the data type: Dword=int or Uint,bool=bool, predefined constants =enum, structure =struct.
 

DllImport will be in order to find the place automatically: 1, exe directory 2, System32 directory 3, environment variable directory so just need you to copy the referenced DLL into these three directories can not write the path or can be such a server. MapPath (. \bin\*.dll) in the Web, but also in the application later found using [DllImport (@ "C:\OJ\Bin\Judge.dll")] to specify the absolute path of the DLL to load normally. This problem most often occurs when using third-party unmanaged DLL components, and mine is the same problem, the official solution for ASP: First you need to confirm which components you refer to, those that are managed, and which are unmanaged. Managed well, directly used to be referenced, The indirect use needs to be copied to the Bin directory. Unmanaged processing can be cumbersome. In fact, you can copy to bin without any help, because the CLR will copy the files to a temporary directory, then run the web, and the CLR will only copy the managed files.  This is why we clearly put the unmanaged DLL under the bin but still hint that the module cannot be loaded.  Here's how it works: first we'll just find a place on the server to create a new directory, if for C:\DLL then, in the environment variable, add this directory to the path variable and finally, copy all the unmanaged files to C:\DLL. or more simply put the DLL into the System32 directory for applications that can be deployed on their own, this is not a solution, however, if we are using virtual space, we are not able to register the path variable or copy our own DLL to the System32 directory.  At the same time we do not necessarily know the physical path of our DLL. DllImport can only use string constants, not Server.MapPath (@ "~/bin/judge.dll") to determine the physical path. Asp. NET to use the DllImport, you must first "using System.Runtime.InteropServices;" However, I found that the call to this "unmanaged DLL" is quite slow, probably because my method requires remote authentication, but it is too slow. After a study, finally think of a perfect solution first we use the








private extern static bool FreeLibrary (IntPtr Lib);

The addresses of the LoadLibrary and GetProcAddress functions are obtained, and the functions within our DLLs are obtained by using these two functions.
We can use Server.MapPath (@ "~/bin/judge.dll") to get the physical path of our DLL, then load it with LoadLibrary, and finally use GetProcAddress to get the function address

The following code for the custom class completes the LoadLibrary mount and function call:

public class Dllinvoke
{
[DllImport ("kernel32.dll")]
private extern static IntPtr LoadLibrary (String path);

[DllImport ("kernel32.dll")]
private extern static IntPtr GetProcAddress (IntPtr lib, String FuncName);

[DllImport ("kernel32.dll")]
private extern static bool FreeLibrary (IntPtr Lib);

Private INTPTR hlib;

Public Dllinvoke (String dllpath)
{
Hlib = LoadLibrary (DllPath);
}

~dllinvoke ()
{
FreeLibrary (hlib);
}

Convert the function you want to execute to a delegate
Public Delegate Invoke (String apiname,type t)
{
INTPTR API = GetProcAddress (hlib, apiname);
Return (Delegate) marshal.getdelegateforfunctionpointer (api,t);
}
}

Called by the following code






Compile (@ "gcc a.c-o a.exe", INF);//This is the compile function defined in the call to my DLL

========================================================

Usage of dllimport:
DllImport ("MyDllImport.dll")]
private static extern int mySum (int a,int b);

The use of the Win32 class library in C # programming
Common Types of correspondence:
1, a DWORD is a 4-byte integer, so we can use an int or uint as the C # corresponding type.
2, bool type and bool corresponding.

Example one: Call the Beep () API to make a sound
Beep () is defined in Kernel32.lib, defined in MSDN, Beep has the following prototypes:
BOOL Beep (DWORD dwfreq,//Sound frequency
DWORD dwduration//sound duration);
Write the following prototypes in C #:
[DllImport ("kernel32.dll")]
public static extern bool Beep (int frequency, int duration);

Example two: enumeration types and Constants
MessageBeep () is defined in User32.lib, defined in MSDN, MessageBeep has the following prototypes:
BOOL MessageBeep (UINT utype//sound type
);

Write the prototype in C #:
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, and it is reasonable to use the enum type for the Utype parameter.
[DllImport ("User32.dll")]
public static extern bool MessageBeep (Beeptype beeptype);

Example three: processing structure
Sometimes I need to determine the battery condition of my laptop. WIN32 provides power management functions for this purpose, and searching MSDN can find the GetSystemPowerStatus () function.
BOOL GetSystemPowerStatus (
Lpsystem_power_status Lpsystempowerstatus
);
This function contains a pointer to a struct that we have not processed. To work with structs, we need to define the structure in C #. We start with an unmanaged definition:
typedef struct _SYSTEM_POWER_STATUS {
BYTE ACLineStatus;
BYTE Batteryflag;
BYTE batterylifepercent;
BYTE Reserved1;
DWORD Batterylifetime;
DWORD BatteryFullLifetime;
} system_power_status, *lpsystem_power_status;
Then, you get the C # version by replacing C type with a C # type.
struct SystemPowerStatus
{
BYTE ACLineStatus;
BYTE Batteryflag;
BYTE BatteryLifePercent;
BYTE reserved1;
int batterylifetime;
int batteryfulllifetime;
}
This makes it easy to write a C # prototype:
[DllImport ("kernel32.dll")]
public static extern bool GetSystemPowerStatus (
Ref SystemPowerStatus SystemPowerStatus);
In this prototype, we use "ref" to indicate that the struct pointer will be passed instead of the structure value. This is the general method of handling the structure passed through the pointer.
This function works fine, but it's a good idea to define the ACLineStatus and Batteryflag fields as enums:
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 structure field is some bytes, we use byte as the basic type of the enum

Example four: Working with strings


Calling C + + code in two C #
int type
[DllImport ("MyDLL.dll")]
Returns an int type
public static extern int MySum (int a1,int B1);
DLL in the Declaration
extern "C" __declspec (dllexport) int WINAPI mySum (int a2,int B2)
{
A2 B2 can't change A1 B1
A2=.
B2= ...
return a+b;
}

Parameter passing int type
public static extern int MySum (ref int A1,REF int B1);
DLL in the Declaration
extern "C" __declspec (dllexport) int WINAPI mySum (int *a2,int *b2)
{
Can change A1, B1
*a2= ...
*b2= ...
return a+b;
}


DLL to be passed into char * type
[DllImport ("MyDLL.dll")]
Incoming value
public static extern int MySum (string astr1,string bstr1);
DLL in the Declaration
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 requires outgoing char * type
[DllImport ("MyDLL.dll")]
Outgoing value
public static extern int MySum (StringBuilder abuf, StringBuilder bbuf);
DLL in the Declaration
extern "C" __declspec (dllexport) int WINAPI mySum (char * Astr,char * BSTR)
{
Outgoing char * Change Astr BSTR-->abuf, BBUF can be changed
return a+b;
}

DLL callback function

BOOL EnumWindows (Wndenumproc lpenumfunc, LPARAM LPARAM)

Using System;
Using System.Runtime.InteropServices;
Public delegate bool CallBack (int hwnd, int lParam); Defining delegate function types
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;
}
[StructLayout (LAYOUTKIND.EXPLICIT)]
public struct Rect
{
[FieldOffset (0)] public int left;
[FieldOffset (4)] public int top;
[FieldOffset (8)] public int right;
[FieldOffset] public int bottom;
}
Class XXXX {
[DllImport ("User32.dll")]
public static extern bool PtInRect (ref Rect. R, point P);
}

. The use of C # in DllImport in net

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.