C #. Net calls an unmanaged DLL

Source: Internet
Author: User
Tags win32 error

1. dll introduction:

Dynamic link library (DLL, or "Dynamic Link Library") is one of the most important components of Microsoft Windows. When you open a Windows system folder, you will find many DLL files, windows implements some major system functions in the form of DLL modules. A Dynamic Link Library cannot be executed directly or receive messages. It is an independent file that contains functions (methods) called by programs or other DLL to complete certain operations ). However, these functions are not part of the execution program, but loaded as needed according to the process's needs.

Ii. Basic Format of C #. Net call:

[Dllimport ("DLL file path")]

Modifier extern return value type method name (parameter list) for example:

[Dllimport ("kernel32.dll", setlasterror = true, entrypoint = "setlocaltime")]
Public static extern int setsystemtime (ref systemtime lpsystemtime );

PS:

1. The DLL file must be located in the current program directory or the system-defined query path (that is, the path set by path in the system environment variable ).

2. dllimport searches for DLL files in sequence (the current program directory> system32 directory> the path set by the Environment Variable path ).

3. The return type variable, method name, and parameter list must be consistent with the definition in the DLL file.

4. Asp.net dllimport path ---- use a third-party Unmanaged DLL (Charles. DLL) when the component is used. when the DLL is copied to the bin directory, the system still prompts that the DLL still cannot be found. (in this case, [dllimport (@ "C: \ programdir \ Charles. DLL ")] can be loaded normally ). The official solutions for ASP. NET team are as follows:

First, confirm which components are referenced? Which are hosted? Which are not managed?

It is very convenient to host and can be referenced directly. for indirect use, you need to copy it to the bin directory. Non-hosted processing is special (in fact, copying to the bin does not work, because CLR will copy the file to a temporary directory and then run the web, the CLR only copies the hosted files, which is why the system still prompts that the module cannot be found when the unmanaged DLL is put in the bin directory ).

Solution: first, create a new directory on the server, which is assumed to be (C: \ programdir \ Windll \). add the directory to the PATH variable in the environment variable, and finally copy all the unmanaged DLL files to the directory. Or simply put the DLL in the System32 directory. This can solve the problem well for applications deployed by yourself. However, if we use a virtual space, can we 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 contain character constants, but cannot use server. mappath to confirm the absolute physical path.

In this case, we need to dynamically obtain the physical path (server. mappath) of our DLL, and obtain the functions in the DLL through the API (load loadlibrary first and obtain the function address getprocaddress ). Related APIs are as follows:

Public class customdllinvoke

{

[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 mlib;

Public customdllinvoke (string dllpath)

{Mlib = loadlibrary (dllpath )}

~ Customdllinvoke () {freelibrary (mlib );}

Public Delegate invoke (string apiname, type T)

{Intptr API = getproaddress (mlib, apiname); Return (delegate) Marshal. getdelegateforfunctionpointer (API, T );}

}

Iii. Message callback

Two Methods of calling a function:

Stdcall: The stdcall call Convention is also called the passcal call Convention. The syntax stated in the call convention is int_stdcall function (int A, int B ). the call conventions of stdcall mean: 1. the parameter is pushed to the stack from right to left. 2. The function modifies the stack. 3. The function name is automatically followed by an underscore. Followed by the parameter size. In C #, the function only supports the stdcall call method.

Cdecl: The cdecl call Convention, also known as the C call Convention, is the default call Convention of C language. Its syntax is int_cdecl function (int A, int B ). the parameter pressure stack sequence of cdecal is the same as that of stdcall. The parameter is first pushed to the stack from right to left. The difference is that the function itself does not clean up the stack, and the caller copies and cleans up the stack. Due to this change, the number of parameters allowed by the C call convention is not fixed, which is also a major feature of C language. VC ++ 6.0 uses the cdecl call method by default.

Therefore, when C # Calls the DLL function through a message, the function cannot be called correctly due to different function call conventions.

Method: 1. Modify the DLL file and support the stdcall call method. 2. manually modify the. Il intermediate file (C # does not support the _ cdecl modifier. the. NET intermediate file. Il is a call method that supports cdecl .)

3. Use VC ++ 7.0 to encapsulate a layer of Shell for Windows DLL. (IN Vc ++ 7.0, you can use the _ cdecl modifier to specify the function call method)

4. demo of complex types (modify the system time of the PC)

Public struct systemtime
{
Public short wyear;
Public short wmonth;
Public short wdayofweek;
Public short wday;
Public short whour;
Public short wminute;
Public short wsecond;
Public short wmilliseconds;
}

[Dllimport ("kernel32.dll", setlasterror = true, entrypoint = "setlocaltime")]
Public static extern int setsystemtime (ref systemtime lpsystemtime );

[Dllimport ("kernel32.dll", setlasterror = true)]
Public static extern long getlasterror ();

Private void button#click (Object sender, eventargs E)
{
Datetime setdt = datetime. parse (this. textbox1.text );
Systemtime ST = new systemtime ();
St. wyear = (short) setdt. Year;
St. wmonth = (short) setdt. month;
St. wday = (short) setdt. Day;
St. whour = (short) setdt. hour;
St. wminute = (short) setdt. minute;
St. wsecond = (short) setdt. Second;
Int result = setsystemtime (ref st );
If (result = 1)
{
MessageBox. Show ("modification successful! ");
}
Else
{
Long errorcode = getlasterror ();
// Int code = marshal. getlastwin32error (); // This method is often used in place of getlasterror API.
MessageBox. Show ("modification failed. Win32 error code is {0}. Please check the meaning list of getlasterror returned values or call formatmessage to view" + errorcode. tostring ());
}
}

PS:

1. Difference Between setlocaltime and setsystemtime: the usage of setlocaltime is basically the same as that of setsystemtime. The difference is that the parameter in setsystemtime specifies the UTC time (International Standard Time), that is, for computers in our region (UTC + 8), the system time will be 8 hours faster than the time set by the systesystemtime parameter)

2. Meaning of getlasterror return value (http://blog.chinaunix.net/u2/82288/showart_1335456.html)

Best regards,

Charles Chen

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.