<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    靈魂-放水

    為學(xué)日益,為道日損。

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks

    本主題說明 DllImport 屬性的常見用法。第一節(jié)討論使用 DllImport 從托管應(yīng)用程序調(diào)用本機(jī)代碼的優(yōu)點(diǎn)。第二節(jié)集中討論封送處理和 DllImport 屬性的各個(gè)方面。

    從托管應(yīng)用程序調(diào)用非托管代碼

    當(dāng)在托管應(yīng)用程序中重用現(xiàn)有的非托管代碼時(shí),DllImport 屬性非常有用。例如,托管應(yīng)用程序可能需要調(diào)用非托管 WIN32 API。

    下面的代碼示例說明此通用方案,此示例將調(diào)用 MessageBox(位于 User32.lib 中):

    #using <mscorlib.dll>
    using namespace System::Runtime::InteropServices; 
    // for DllImportAttribute
    
    namespace 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 );
    }

    主要注意包含 DllImport 的代碼行。此代碼行根據(jù)參數(shù)值通知編譯器,使之聲明位于 User32.dll 中的函數(shù)并將簽名中出現(xiàn)的所有字符串(如參數(shù)或返回值)視為 Unicode 字符串。如果缺少 EntryPoint參數(shù),則默認(rèn)值為函數(shù)名。另外,由于 CharSet 參數(shù)指定 Unicode,因此公共語(yǔ)言運(yùn)行庫(kù)將首先查找稱為 MessageBoxW(有 W 是因?yàn)?Unicode 規(guī)范)的函數(shù)。如果運(yùn)行庫(kù)未找到此函數(shù),它將根據(jù)調(diào)用約定查找 MessageBox 以及相應(yīng)的修飾名。受支持的調(diào)用約定只有 __cdecl__stdcall

    當(dāng)調(diào)用用戶定義的 DLL 中所包含的函數(shù)時(shí),有必要將 extern "C" 添加在 DLL 函數(shù)聲明之前,如下所示:

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

    有關(guān)受支持的其他參數(shù)值的更多信息,請(qǐng)參見 DllImport

    將非結(jié)構(gòu)化參數(shù)由托管封送處理為非托管

    除使用上述方法外,還可以使用另一種方法將托管參數(shù)(來自托管應(yīng)用程序)封送處理為非托管參數(shù)(在非托管 DLL 中)。

    以下代碼示例說明封送處理技術(shù):

    #using <mscorlib.dll>
    using namespace System; // To bring System::String in
    using namespace System::Runtime::InteropServices; 
    // for DllImportAttribute
    namespace 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);
    }

    完成實(shí)際的調(diào)用后,由于 CharSet 參數(shù)值的作用,所有參數(shù)字符串都自動(dòng)轉(zhuǎn)換為 wchar_t*。同樣,所有 Int32 參數(shù)類型都轉(zhuǎn)換為非托管 int,而 UInt32 參數(shù)類型轉(zhuǎn)換為非托管 unsigned int

    下表提供關(guān)于轉(zhuǎn)換非托管和托管上下文的指導(dǎo):

    非托管代碼 C++ 的托管擴(kuò)展
    int Int32
    unsigned int UInt32
    short Int16
    char* 用于 [in] 參數(shù)的 String* (CharSet = Ansi),用于 [out] 參數(shù)或返回值的 Text::StringBuilder*
    wchar_t* 用于 [in] 參數(shù)的 String* (CharSet = Unicode),用于 [out] 參數(shù)或返回值的 Text::StringBuilder*
    函數(shù)指針(回調(diào))
    限制:函數(shù)指針必須具有 __stdcall 調(diào)用約定,因?yàn)檫@是 DllImport 支持的唯一類型。
    委托類型
    數(shù)組(如 wchar_t*[])
    限制:CharSet 參數(shù)僅應(yīng)用于函數(shù)參數(shù)的根類型。因此,無(wú)論 CharSet 的值是什么,String* __gc[] 都將被封送處理為 wchar_t* []
    相應(yīng)類型的托管數(shù)組(如 String*__gc[]

    將結(jié)構(gòu)化類型由非托管封送處理為托管

    除簡(jiǎn)單類型外,運(yùn)行庫(kù)還提供了一種機(jī)制,可以將簡(jiǎn)單結(jié)構(gòu)由托管上下文封送處理為非托管上下文。簡(jiǎn)單結(jié)構(gòu)不包含任何內(nèi)部數(shù)據(jù)成員指針、結(jié)構(gòu)化類型的成員或其他元素。

    例如,本主題顯示如何調(diào)用本機(jī) DLL 中具有以下簽名的函數(shù):

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

    若要?jiǎng)?chuàng)建此函數(shù)的托管包裝,請(qǐng)將 StructLayout 屬性應(yīng)用到調(diào)用類。此屬性確定封送處理結(jié)構(gòu)時(shí)結(jié)構(gòu)的組織方式。若要確保以傳統(tǒng)的 C 格式組織結(jié)構(gòu),請(qǐng)指定順序布局 (LayoutKind::Sequential)。結(jié)果代碼如下:

    #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
    }

    也可以在托管應(yīng)用程序中使用 __nogc 關(guān)鍵字,以確保不發(fā)生封送處理:

    #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;
    }

    第二個(gè)方案是:

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

    注意參數(shù)是通過值傳遞的。若要在托管應(yīng)用程序中包裝此調(diào)用,請(qǐng)使用值而不是 __gc 類型。結(jié)果代碼如下:

    #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
    }

    請(qǐng)參見

    屬性演練

    posted on 2006-09-14 16:24 放水老倌 閱讀(991) 評(píng)論(0)  編輯  收藏 所屬分類: .NET
    主站蜘蛛池模板: 老司机福利在线免费观看| 久久亚洲私人国产精品| 免费大学生国产在线观看p| 免费无码一区二区三区蜜桃大 | 亚洲网站在线播放| 亚洲国产精品国自产拍电影| 亚洲第一视频网站| 亚洲视频在线观看地址| 国产精品亚洲精品| 亚洲精品乱码久久久久久蜜桃图片| 亚洲中文字幕无码av| 欧美亚洲精品一区二区| 日韩毛片免费一二三| 中国一级特黄的片子免费| 美女在线视频观看影院免费天天看| 久久久久久AV无码免费网站下载| 午夜免费福利视频| 国产又黄又爽又猛免费app| 全免费a级毛片免费**视频| 又爽又高潮的BB视频免费看 | 亚洲免费人成视频观看| 欧美最猛性xxxxx免费| 在线视频免费国产成人| 亚洲高清无码专区视频| 亚洲gv白嫩小受在线观看| 亚洲精品国产成人| 婷婷亚洲综合五月天小说在线| 国产成人无码精品久久久久免费| 日本免费高清视频| 成人免费看片又大又黄| 亚洲国产综合久久天堂| 亚洲第一中文字幕| 亚洲国产午夜精品理论片在线播放 | 国产成人在线观看免费网站| 亚洲精品视频免费| 99亚洲精品高清一二区| 亚洲欧洲无码一区二区三区| 国产乱妇高清无乱码免费| 91高清免费国产自产拍2021| 成人毛片免费视频| 国产亚洲精久久久久久无码AV|