Use the dllimport attribute

Source: Internet
Author: User

This topic describes common usage of the dllimport attribute. Section 1 DiscussionDllimportAdvantages of calling local code from a hosted application. Section 2 focuses on sending and receiving andDllimportAttributes.

Call unmanaged code from a hosted application

When you reuse existing unmanaged code in a hosted application,DllimportAttribute is very useful. For example, a hosted application may need to call an unmanaged Win32 API.

The following code example describes the general scheme. MessageBox (in user32.lib) is called ):

#using <mscorlib.dll>using namespace System::Runtime::InteropServices; // for DllImportAttributenamespace SysWin32{   [DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]   int MessageBox(void* hWnd, wchar_t* lpText, wchar_t* lpCaption,                   unsigned int uType);}int main( ){   SysWin32::MessageBox( 0, L"Hello world!", L"Greetings", 0 );}

Important Notes includeDllimport. This code line notifies the compiler based on the parameter value to declare the function in user32.dll and treats all strings (such as parameters or return values) in the signature as Unicode strings. IfEntryPointParameter, the default value is the function name. In addition, becauseCharSetThe parameter specifies Unicode. Therefore, the Runtime Library of the common language is calledMessageboxw(W is a unicode Specification) function. If this function is not found in the running database, it will be searched according to the call conventions.MessageBoxAnd the corresponding modifier name. Supported call Conventions only_ CdeclAnd_ Stdcall.

When calling the functions contained in a User-Defined DLL, it is necessary extern "C"Before adding the DLL function declaration, it is shown as follows:

// The function declaration in SampleDLL.h fileextern "C" SAMPLEDLL_API int fnSampleDLL(void);

For more information about supported other parameter values, see dllimport.

Hosting and sending unstructured parameters is not managed

In addition to the preceding method, you can use another method to encapsulate managed parameters (from managed applications) into unmanaged parameters (In unmanaged DLL ).

The following code example describes the sending and receiving processing technology:

#using <mscorlib.dll>using namespace System; // To bring System::String inusing namespace System::Runtime::InteropServices; // for DllImportAttributenamespace SysWin32{   [DllImport("user32.dll", EntryPoint = "MessageBox", CharSet = Unicode)]   Int32 MessageBox( Int32 hWnd, String* lpText, String* lpCaption,                      UInt32 uType );}int main( ){   SysWin32::MessageBox(0, S"Hello world!", S"Greetings", 0);}

After the actual call is completedCharSetFunction of the parameter value. All parameter strings are automatically convertedWchar_t *. Similarly, allInt32All parameter types are converted to unmanagedInt, AndUint32Parameter type conversion is not managedUnsigned int.

The following table provides guidance on the conversion of unmanaged and managed contexts:

Unmanaged code C ++ managed Extension
Int Int32
Unsigned int Uint32
Short Int16
Char * Used for the [in] ParameterString *(Charset = ANSI), used for the [out] parameter or return valueText: stringbuilder *.
Wchar_t * Used for the [in] ParameterString *(Charset = Unicode), used for the [out] parameter or return valueText: stringbuilder *.
Function pointer (callback)
Restrictions: The function pointer must have_ StdcallCall convention, because this isDllimportThe unique type supported.
Delegate type
Array (such as wchar_t * [])
Restrictions: The charset parameter is only applicable to the root type of the function parameter. Therefore, no matter what the charset value is,String * _ GC []Both are sentWchar_t * [].
Corresponding types of hosted arrays (suchString * _ GC [])
Process the structured type from unmanaged messages to managed messages

In addition to the simple type, the runtime provides a mechanism to block a simple structure from a hosted context to a non-hosted context. A simple structure does not contain any internal data member pointers, structural members, or other elements.

For example, this topic shows how to call a function with the following signature in the local dll:

#include <stdio.h>struct S{   char* str;   int n;};int __cdecl func( struct S* p ){   printf( "%s\n", p->str );   return p->n;}

To create a managed packaging for this function, apply the structlayout attribute to the call class. This attribute determines the structure of the sending and receiving structure. To ensure that the structure is organized in the traditional C format, specify the sequential layout (LayoutKind::Sequential). The result code is as follows:

#using <mscorlib.dll>using namespace System;using namespace System::Runtime::InteropServices;// CharSet = Ansi(Unicode) means that everything that is a string // in this structure should be marshaled as Ansi(Unicode) // strings[StructLayout( LayoutKind::Sequential, CharSet=Ansi )]__gc class MS // To be compatible with the type in the native // code, this structure should have the members laid out in// the same order as those in the native struct{public:   String* m_str;   Int32 m_n;};[DllImport("some.dll")]Int32 func( MS* ptr );int main( ){   MS* p = new MS;   p->m_str = S"Hello native!";   p->m_n = 7;   Console::WriteLine(func(p)); // Should print 7}

You can also use the _ nogc keyword in the Managed Application to ensure that the mail is not sent for processing:

#include <stdlib.h>#include <string.h>#using <mscorlib.dll>using namespace System;using namespace System::Runtime::InteropServices;__nogc class UMS{public:   char* m_str;   int m_n;};[DllImport("some.dll")]Int32 func( UMS* ptr );int main( ){   UMS* p = new UMS;   p->m_str = strdup( "Hello native!" );   p->m_n = 7;   Console::WriteLine(func(p)); // Should print 7   free( p->m_str );   delete p;}

The second solution is:

#include <stdio.h>struct S{   wchar_t* str;   int n;};int __cdecl func( struct S p ){   printf( "%S\n", p.str );   return p.n;}

Note that parameters are passed through values. To wrap this call in a hosted application, use the value instead of the _ GC type. The result code is as follows:

#using <mscorlib.dll>using namespace System;using namespace System::Runtime::InteropServices;[StructLayout( LayoutKind::Sequential, CharSet=Unicode )]__value class VS{public:   String* m_str;   Int32 m_n;};[DllImport( "some.dll" )]Int32 func( VS ptr );int main( ){   VS v;   v.m_str = S"Hello native!";   v.m_n = 7;   Console::WriteLine(func(v)); // should print 7 also}

Use the dllimport attribute

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.