Create the Win32 DLL and call it inside C #

Source: Internet
Author: User
Tags bool garbage collection modifiers numeric value win32 visual studio
Create

This is a collection of three of technical articles collected online, explaining how to create a Win32 DLL, and then how to invoke this DLL's tutorial in C #.

The first is the article that creates the Win32 DLL. The article that explains this is everywhere, here give an article I read: http://www.flipcode.com/articles/article_creatingdlls.shtml. Win32 DLL creation in fact, in Visual Studio has given a better template, just need to note that some XXX_API macros did not add extern "C", which will cause in C # to find this function error. So, keep in mind that the function must be defined as extern "C".

The second article to http://edu.100down.com/it/program/Csharp/105256797.html, the following is posted content:

The Platform invoke service (PInvoke) allows managed code to call unmanaged functions implemented in DLLs.

This tutorial describes what you can use to call unmanaged DLL functions from C #. The properties discussed in this tutorial allow you to call these functions and send the data types to the correct marshaling.

Tutorial

C # code has the following two methods that can call unmanaged code directly:

    • Directly invokes a function exported from a DLL.
    • Invokes an interface method on a COM object (for more information, see COM Interop Part I: C # Client Tutorial).

For both techniques, you must provide the C # compiler with the declaration of the unmanaged function, and you may also need to provide the C # compiler with instructions on how to marshal parameters and return values passed between and unmanaged code.

The tutorial consists of the following topics:

    • Calling DLL export directly from C #
    • default marshaling and specifying custom marshaling for parameters of unmanaged methods
    • Specify custom marshaling for user-defined structures
    • Registering Callback methods

The tutorial includes the following examples:

    • Example 1 uses DllImport
    • Example 2 overriding default marshaling
    • Example 3 Specifies a custom marshaling

Calling DLL export directly from C #

To declare a method that has an implementation from the DLL export, do the following:

    • Use the C # keyword static and extern declaration methods.
    • Attaches the DllImport property to the method. The DllImport property allows you to specify the name of the DLL that contains the method. It is common practice to name a C # method with the same names as the exported method, but you can also use a different name for the C # method.
    • You can also specify custom marshaling information for the parameters and return values of a method, which overrides the default marshaling for the. NET Framework.

Example 1

This example shows how to use the DllImport property to pass msvcrt.dll the output message in the call puts .

Pinvoketest.csusing system;using system.runtime.interopservices;class platforminvoketest{    [DllImport (" Msvcrt.dll ")] public    static extern int puts (string c);    [DllImport ("Msvcrt.dll")]    internal static extern int _flushall ();    public static void Main ()     {        puts ("Test");        _flushall ();    }

Output

Test

Code Discussion

The preceding example shows the minimum requirements for declaring a C # method implemented in an unmanaged DLL. PlatformInvokeTest.putsmethod is declared with the static and extern modifiers and has the DllImport property, which notifies the puts compiler of this implementation from by using the default name msvcrt.dll . To use a different name (such as) for a C # method putstring , you must use the entrypoint option in the DllImport property, as follows:

[DllImport ("Msvcrt.dll", entrypoint= "puts")]

For more information about the syntax of the DllImport property, see the DllImportAttribute class.

default marshaling and specifying custom marshaling for parameters of unmanaged methods

When you call an unmanaged function from C # code, the common language runtime must marshal parameters and return values.

There is a default unmanaged type for each. NET Framework type that the common language runtime uses to marshal data in managed to unmanaged function calls. For example, the default marshaling of a C # string value is a type that is marshaled to LPTSTR (a pointer to a TCHAR character buffer). You can override the default marshaling using the MarshalAs property in the C # declaration of an unmanaged function.

Example 2

This example uses the DllImport property to output a string. It also shows how to override the default marshaling of function arguments by using the MarshalAs property.

Marshal.csusing system;using system.runtime.interopservices;class platforminvoketest{    [DllImport (" Msvcrt.dll ")] public    static extern int puts (        [MarshalAs (UNMANAGEDTYPE.LPSTR)]        string m);    [DllImport ("Msvcrt.dll")]    internal static extern int _flushall ();    public static void Main ()     {        puts ("Hello world!");        _flushall ();    }

Output

When you run this example, the string

Hello world!

will be displayed on the console.

Code Discussion

In the preceding example, the puts default marshaling of a function's arguments has been overridden from the default value LPTSTR to LPSTR.

The MarshalAs property can be placed on method parameters, method return values, and fields of structs and classes. To marshal the method return value, place the MarshalAs property in the property block on the method, along with the Return property location rewrite. For example, to explicitly set puts the marshaling of a method return value:

... [DllImport ("Msvcrt.dll")] [Return:marshalas (UNMANAGEDTYPE.I4)]public static extern int puts (...)

For more information about the syntax of the MarshalAs property, see the MarshalAsAttribute class.

Note The in and out properties can be used to annotate the parameters of an unmanaged method. They work in the same way as the in and out modifiers in the MIDL source file. Note that the out property differs from the C # parameter modifier out. For More information about in and out properties, see InAttribute Classes and OutAttribute classes.

Specify custom marshaling for user-defined structures

You can specify custom marshaling properties for fields that are passed to unmanaged functions or to structures and classes returned from unmanaged functions. You can do this by adding the MarshalAs property to a field in a struct or class. You must also use the StructLayout property to set the layout of the structure, control the default marshaling of string members, and set the default package size.

Example 3

This example shows how to specify a custom marshaling property for a structure.

Please consider the following C structure:

typedef struct TAGLOGFONT {    LONG lfheight;    LONG Lfwidth;    LONG lfescapement;    LONG lforientation;    LONG Lfweight;    BYTE Lfitalic;    BYTE Lfunderline;    BYTE lfstrikeout;    BYTE lfCharSet;    BYTE lfoutprecision;    BYTE lfclipprecision;    BYTE lfquality;    BYTE lfpitchandfamily;    

In C #, you can use the structlayout and MarshalAs properties to describe the previous structure, as follows:

logfont.cs//compile with:/target:moduleusing system;using System.Runtime.InteropServices; [StructLayout (layoutkind.sequential)]public class LogFont {public     const int lf_facesize =;    public int lfheight;     public int lfwidth;     public int lfescapement;     public int lforientation;     public int lfweight;     public byte Lfitalic;     public byte Lfunderline;     public byte lfstrikeout;     public byte lfCharSet;     public byte lfoutprecision;     public byte lfclipprecision;     public byte lfquality;     public byte lfpitchandfamily;    [MarshalAs (UnmanagedType.ByValTStr, sizeconst=lf_facesize)]    public string Lffacename; }

For more information about the syntax of the StructLayout property, see the StructLayoutAttribute class.

You can then use the structure in C # code, as follows:

pinvoke.cs//compile with:/addmodule:logfont.netmoduleusing system;using System.Runtime.InteropServices; Class platforminvoketest{[DllImport ("Gdi32.dll", CharSet=CharSet.Auto)] public static extern IntPtr Createfo       Ntindirect ([In, MarshalAs (unmanagedtype.lpstruct)] logfont LPLF//characteristics);       [DllImport ("Gdi32.dll")] public static extern bool DeleteObject (INTPTR handle);            public static void Main () {logfont lf = new LogFont ();            Lf.lfheight = 9;            Lf.lffacename = "Arial";             INTPTR handle = CreateFontIndirect (LF);            if (IntPtr.Zero = = handle) {Console.WriteLine ("Can ' t creates a logical font."); else {if (intptr.size = 4) Console.wri Teline ("{0:x}", handle.)                  ToInt32 ()); else ConsOle. WriteLine ("{0:x}", handle.)                           ToInt64 ());                  Delete the logical font created. if (!            DeleteObject (handle)) Console.WriteLine ("Can ' t delete the logical font"); }      }}

Running the sample

C30a0ae5

Code Discussion

In the previous example, the CreateFontIndirect method uses an argument of the LogFont type. The MarshalAs and in properties are used to qualify this parameter. The program displays the numeric value returned by this method as a hexadecimal uppercase string.

Registering Callback methods

To register a managed callback that calls an unmanaged function, declare a delegate with the same argument list and pass an instance of it through PInvoke. On the unmanaged side, it will appear as a function pointer. For more information about PInvoke and callbacks, see platform invoke details.

For example, consider the following unmanaged function MyFunction , which requires callback as one of its parameters:

typedef void (__stdcall *pfn_mycallback) (); int __stdcall MyFunction (pfn_ mycallback);

To call from managed code MyFunction , declare the delegate, attach the DllImport to the function declaration, and marshal any parameters or return values as needed:

public delegate void Mycallback (); [DllImport ("Mydll.") DLL ")]public static extern void MyFunction (Mycallback callback);

Also, make sure that the lifetime of the delegate instance overwrites the lifetime of unmanaged code, otherwise the delegate is no longer available after garbage collection.

The third article comes from http://www.njpro.cn/8918/ShowPost.aspx, a table about the data types in C/A + + and C #.

unmanaged unmanaged
types in Wtypes.hC language type managed class name Description
HANDLE void* System.IntPtr 32-bit
BYTE unsigned char System.Byte 8-bit
Short Short System.Int16 16-bit
Word unsigned short System.UInt16 16-bit
Int Int System.Int32 32-bit
UINT unsigned int System.UInt32 32-bit
LONG Long System.Int32 32-bit
BOOL Long System.Int32 32-bit
DWORD unsigned long System.UInt32 32-bit
ULONG unsigned long System.UInt32 32-bit
CHAR Char System.Char Decorated with ANSI.
LPSTR char* System.String or System.stringbuilder Decorated with ANSI.
Lpcstr Const char* System.String or System.stringbuilder Decorated with ANSI.
LPWStr wchar_t* System.String or System.stringbuilder Decorated with Unicode.
Lpcwstr Const wchar_t* System.String or System.stringbuilder Decorated with Unicode.
FLOAT Float System.Single 32-bit
DOUBLE Double



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.