青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

twzheng's cppblog

『站在風(fēng)口浪尖緊握住鼠標(biāo)旋轉(zhuǎn)!』 http://www.cnblogs.com/twzheng

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  136 隨筆 :: 78 文章 :: 353 評(píng)論 :: 0 Trackbacks
您也使用托管C++嗎?
摘自:沐楓小筑 (博客園博客)

轉(zhuǎn)向.NET后,手頭上往往仍有舊的模塊要重用。也許這些模塊是Delphi寫的,也許是C/C++寫的,或者是其它編程語言……為了能把它們移植到.NET下,或者是在.NET中調(diào)用,To be or not to be, that is a question。
  在這里,我筆記了幾個(gè)在工作中遇到的幾個(gè)場(chǎng)景。不過,這里不包括完全使用C#來重寫原來用C++編寫的程序這種變態(tài)的需求。當(dāng)你被要求做這種事的時(shí)候,請(qǐng)三思而后行……這簡(jiǎn)直是種非人的折磨。

您也使用托管C++嗎?  如沐楓林

  場(chǎng)景一:在.NET中調(diào)用WindowsAPI或DLL。

  這是比較普遍的需求。一般來說,簡(jiǎn)單的函數(shù)調(diào)用,大可直接用C#/VB.NET,經(jīng)過DllImport屬性包裝出函數(shù)來調(diào)用。如:
[DllImport("KERNEL32.DLL", EntryPoint="MoveFileW",  SetLastError=true,
CharSet
=CharSet.Unicode, ExactSpelling=true,
CallingConvention
=CallingConvention.StdCall)]
public static extern bool MoveFile(String src, String dst);


  由于WindowsAPI用到的人實(shí)在是多,因此有一個(gè)專門的wiki站點(diǎn),收集這方面的資料:http://www.pinvoke.net/,對(duì)于常用的函數(shù)甚至有完整的應(yīng)用例子和幫助。當(dāng)然,如果你有相應(yīng)的資料和例子,你也可以貢獻(xiàn)你的力量,給其它人幫助。

   場(chǎng)景二:用托管C++包裝現(xiàn)有的DLL,供C#調(diào)用

  當(dāng)函數(shù)的參數(shù)或返回值比較復(fù)雜,或函數(shù)比較多的時(shí)候,這種方法對(duì)與人來說,實(shí)在是一個(gè)折磨。常常這些接口和定義就要用掉幾千行的代碼,而且還不能保證是正確的。這些錯(cuò)誤往往在運(yùn)行時(shí)才能顯現(xiàn)出來,甚至有些錯(cuò)誤會(huì)引起內(nèi)存泄漏,或其它更為隱蔽的錯(cuò)誤。
  在這種情況下,使用C++/Managed代碼來包裝,就成了最合理的選擇。因?yàn)橥泄蹸++代碼可以直接引用原有的頭文件,直接調(diào)用非托管函數(shù),而不需要聲明。這樣,既減少了工作量,又避免引入錯(cuò)誤。缺點(diǎn)是,這種方法會(huì)增加一個(gè)DLL。要注意的是托管字符串和非托管字符串是有區(qū)別的,并需要轉(zhuǎn)換(特別要注意的Unicode字符串和多字節(jié)字符串的轉(zhuǎn)換)。

  仍以MoveFile為例吧,這樣比較簡(jiǎn)單:

#include <windows.h>
#include 
<vcclr.h>

using namespace System;

namespace wrapper
{
    
public ref class ApiWrapper {
    
public:
        
bool static MoveFile(String ^ lpExistingFileName, String ^ lpNewFileName )
        
{
            pin_ptr
<const wchar_t> src = PtrToStringChars(lpExistingFileName);
            pin_ptr
<const wchar_t> dst = PtrToStringChars(lpNewFileName);
            
return ::MoveFile(src, dst);
        }

    }
;
}

  然后在C#中,引用上面代碼生成的DLL文件,就可以直接調(diào)用了:
wrapper.ApiWrapper.MoveFile(@"c:\debug.log"@"c:\debug.txt");

  假如原有的代碼是基于COM的,那么太好了,VisualStudio等IDE會(huì)自動(dòng)生成一個(gè)用于包裝的dll,供你調(diào)用。當(dāng)然因特殊需要而手工編碼的是另一回事。

  場(chǎng)景三:現(xiàn)有C++原代碼,包裝后供C#調(diào)用。

  C++的原代碼,實(shí)際上可以直接編譯成托管代碼。MFC也好ATL也好……這樣看起來在.NET中最強(qiáng)大的編程語言就是C++了:它不僅可以編寫托管程序,甚至可以將標(biāo)準(zhǔn)C++的代碼也編譯成托管程序!其實(shí)VC++最強(qiáng)大的地方不止如此,它還在于能夠編寫混合了托管和非托管的代碼的程序!!!這樣最大的好處不僅可以將關(guān)鍵代碼直接編譯成非托管的代碼,還可以避免被反編譯。
  
  假設(shè)現(xiàn)有C++代碼如下:
class UnmanagedClass {
public:
    LPCWSTR GetPropertyA() 
return L"Hello!"; }
    
void MethodB( LPCWSTR ) {}
}
;
  我們只要再增加一個(gè)包裝類到工程文件中:
namespace wrapper
{
    
public ref class ManagedClass {
    
public:
        
// Allocate the native object on the C++ Heap via a constructor
        ManagedClass() : m_Impl( new UnmanagedClass ) {}

        
// Deallocate the native object on a destructor
        ~ManagedClass() {
            delete m_Impl;
        }


    
protected:
        
// Deallocate the native object on the finalizer just in case no destructor is called
        !ManagedClass() {
            delete m_Impl;
        }


    
public:
        property String 
^  get_PropertyA {
            String 
^ get() {
                
return gcnew String( m_Impl->GetPropertyA());
            }

        }


        
void MethodB( String ^ theString ) {
            pin_ptr
<const WCHAR> str = PtrToStringChars(theString);
            m_Impl
->MethodB(str);
        }


    
private:
        UnmanagedClass 
* m_Impl;
    }
;
}

  然后,改變編譯選項(xiàng)為“使用公共語言擴(kuò)展 /clr”就可以了。這樣,我們把代碼編譯成DLL文件就可以供.NET其它語言調(diào)用了。
  最后,C#中可以象如下的代碼一樣調(diào)用C++類了:
ManagedClass mc = new ManagedClass();
mc.MethoB(
"Hello");
string s = mc.get_PropertyA;

  場(chǎng)景四:如何在托管C++代碼中混合托管和非托管代碼

  很簡(jiǎn)單,只要從#pragma unmanaged編譯指示開始的程序,一率編譯成非托管代碼;要想恢復(fù)成托管代碼,只要使用#pragma managed就可以了。如:
  
#pragma unmanaged

#include 
<iostream>
using namespace std;

template
<typename T>
void f(T t){
    cout 
<< t << endl;
}


#pragma managed

using namespace System;

void m(String ^ s){
    Console::WriteLine(s);
}


void main(){
    f(
"Hello");
    m(
"World");
}
  
  生成exe文件后,用反編譯程序查看 f 函數(shù):
[PreserveSig, MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType=MethodCodeType.Native), SuppressUnmanagedCodeSecurity]
public static unsafe void modopt(CallConvCdecl) f<char const *>(sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)*);
  
  看不到源碼,而方法屬性標(biāo)記為Unmanaged。
  如果沒有加上#pragma unmanaged,反編譯得到的 f 函數(shù)為:
internal static unsafe void modopt(CallConvCdecl) f<char const *>(sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)* t)
{
      std.basic_ostream
<char,std::char_traits<char> >.<<(std.operator<<<struct std::char_traits<char> >(*((basic_ostream<char,std::char_traits<char> >* modopt(IsImplicitlyDereferenced)*&__imp_std.cout), t), (basic_ostream<char,std::char_traits<char> >* modopt(IsImplicitlyDereferenced) modopt(CallConvCdecl) *(basic_ostream<char,std::char_traits<char> >* modopt(IsImplicitlyDereferenced))) __unep@?endl@std@@$$FYAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z);
}

  其中的函數(shù)內(nèi)容一目了然。如果你的函數(shù)沒有調(diào)用operator等不好理解的類庫,那么反編譯出來的代碼簡(jiǎn)直和源碼沒差別。 

  開心一刻:我只會(huì)C++不懂.NET不懂C#,怎么編寫.NET程序?

  很簡(jiǎn)單,你照樣用你的C++寫你的程序,然后測(cè)試沒有錯(cuò)誤后,將編譯選項(xiàng)改為/clr,好了,Rebuild,你的程序現(xiàn)在是.NET了。

  惡搞:“我想問一下,在能將現(xiàn)有的C++代碼直接進(jìn)行封裝,被C#進(jìn)行調(diào)用,而不是去調(diào)用DLL,也就是不生成DLL,就在C#下能直接調(diào)用VC的工程源文件不?”

  我想,提問的人是不是指,現(xiàn)有c++源碼,但不想費(fèi)勁去轉(zhuǎn)換成C#源碼,但又想能與C#一起編譯。
  于是我就給了一個(gè)極其變態(tài)的方法,不過,個(gè)人是不建議使用這種變態(tài)的方法啊。方法如下:
  1 先將C++源碼,改用CLR編譯選項(xiàng),編譯成.NET的Assembly(DLL文件)。
  2 然后用reflector等反編譯軟件,反編譯成C#代碼,并導(dǎo)出(reflector有專門的導(dǎo)出插件)。
  3 將導(dǎo)出的C#代碼,添加上新寫的C#代碼一起編譯。
  
  這種方法生成的代碼很是恐怖,強(qiáng)烈建議不要把C++源碼就這么丟了,否則后果自負(fù)。

  場(chǎng)景五:不想要DLL,能不能直接把C++源代碼與C#源代碼一起編譯成一個(gè)單獨(dú)的Assembly呢?

  當(dāng)然是可以的。具體參見:讓C++代碼與C#代碼一起生成一個(gè)單一的Assembly

-------
部份例子來自MSDN.

posted on 2007-05-19 17:36 譚文政 閱讀(481) 評(píng)論(0)  編輯 收藏 引用 所屬分類: vc++.net
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            香蕉免费一区二区三区在线观看| 午夜电影亚洲| 欧美视频一二三区| 欧美区高清在线| 欧美日韩不卡一区| 国产精品成人va在线观看| 国产精品久久久久久久电影| 国产精品日韩一区| 韩国av一区| 亚洲精品一区中文| 夜夜狂射影院欧美极品| 男人的天堂亚洲在线| 欧美寡妇偷汉性猛交| 亚洲激情成人在线| 亚洲特色特黄| 久久综合福利| 欧美性猛交99久久久久99按摩| 国产精品欧美久久| 欲色影视综合吧| 一区二区冒白浆视频| 欧美在线观看你懂的| 老鸭窝毛片一区二区三区| 亚洲黄一区二区三区| 亚洲欧美日韩人成在线播放| 久久久久九九九| 国产精品av久久久久久麻豆网| 国产婷婷成人久久av免费高清| 在线观看中文字幕亚洲| 亚洲字幕一区二区| 欧美成人午夜激情| 性欧美xxxx视频在线观看| 欧美精品福利在线| 在线国产亚洲欧美| 欧美一区二区三区免费观看视频| 亚洲第一黄色| 久久久久久久999精品视频| 国产精品久久久久久久久久久久 | 欧美日韩中文在线| 狠狠狠色丁香婷婷综合久久五月| 中文精品视频| 亚洲国产精品一区二区第一页| 亚洲摸下面视频| 欧美日韩在线三区| 亚洲精品韩国| 欧美成人伊人久久综合网| 午夜亚洲伦理| 国产女人水真多18毛片18精品视频| 99精品欧美一区二区蜜桃免费| 久久久久久久欧美精品| 亚洲欧美日韩国产成人精品影院| 欧美日韩国产成人| 亚洲看片免费| 亚洲人www| 欧美激情视频在线播放| 亚洲精品久久视频| 亚洲国产成人精品女人久久久 | 亚洲人成网站色ww在线| 欧美成年人在线观看| 亚洲国产欧美国产综合一区| 久久久久久久综合色一本| 欧美极品影院| 麻豆freexxxx性91精品| 在线不卡中文字幕播放| 久久久97精品| 久久aⅴ乱码一区二区三区| 国产日韩欧美麻豆| 久久久青草婷婷精品综合日韩 | 免费久久99精品国产自在现线| 香蕉乱码成人久久天堂爱免费| 国产伦精品一区二区| 久久国产欧美精品| 久久精品国产第一区二区三区最新章节| 国产精品一区视频| 久久精品最新地址| 久久久免费精品视频| 136国产福利精品导航| 欧美国产精品一区| 欧美丰满高潮xxxx喷水动漫| 一个色综合导航| 一级日韩一区在线观看| 国产精品网站在线播放| 久久免费视频网| 欧美激情第二页| 欧美精品在线免费| 欧美一区=区| 久久精品伊人| 亚洲韩日在线| 制服丝袜亚洲播放| 激情综合色综合久久综合| 亚洲高清不卡av| 国产精品二区影院| 久久性天堂网| 欧美日韩一区国产| 久久久精彩视频| 欧美国内亚洲| 久久精品亚洲| 欧美激情一区二区三区| 香蕉尹人综合在线观看| 麻豆成人小视频| 欧美一区二区视频97| 鲁大师影院一区二区三区| 亚洲伊人久久综合| 巨乳诱惑日韩免费av| 正在播放亚洲一区| 久久久综合香蕉尹人综合网| 亚洲午夜一二三区视频| 久久免费精品视频| 亚洲欧美综合另类中字| 欧美激情一区二区三区在线| 久久漫画官网| 国产精品久久久久9999吃药| 欧美不卡在线视频| 国产欧美va欧美va香蕉在| 亚洲第一中文字幕在线观看| 国产裸体写真av一区二区| 亚洲精品一品区二品区三品区| 国产自产精品| 亚洲综合三区| 亚洲一区在线播放| 欧美精品在线视频观看| 免费h精品视频在线播放| 国产精品久久久久婷婷| 欧美日韩成人免费| 艳女tv在线观看国产一区| 久久大综合网| 欧美在线视频全部完| 欧美性天天影院| 亚洲欧洲综合另类在线| 在线成人激情| 欧美一级一区| 久久精品人人做人人综合| 欧美午夜在线观看| 夜夜精品视频一区二区| 9l国产精品久久久久麻豆| 你懂的视频欧美| 欧美国产综合视频| 亚洲国产精品va在看黑人| 久久国产精品久久国产精品| 久久se精品一区精品二区| 国产九九精品| 欧美一区影院| 久久久www| 黄色精品网站| 久久夜色精品一区| 欧美福利视频一区| 亚洲国产精品久久精品怡红院 | 亚洲一二区在线| 亚洲欧美一级二级三级| 国产精品人人做人人爽人人添| 亚洲一线二线三线久久久| 欧美一区二区高清| 国产一区二区无遮挡| 久久精品亚洲精品| 欧美二区视频| 夜夜爽av福利精品导航 | 91久久精品国产91久久| 欧美成人在线免费观看| 亚洲精品一区二| 亚洲欧美制服另类日韩| 国语对白精品一区二区| 欧美精品激情| 亚洲自啪免费| 欧美国产精品中文字幕| 亚洲一区二区在线看| 黄色欧美日韩| 欧美日韩免费看| 午夜精品成人在线视频| 欧美成年人视频| 亚洲——在线| 亚洲电影av在线| 国产精品豆花视频| 久久综合给合久久狠狠狠97色69| 亚洲精品日韩在线| 久久久www免费人成黑人精品| 亚洲国产精品一区二区第一页| 欧美日韩亚洲成人| 久久久国产一区二区| 亚洲精品乱码视频| 久久全国免费视频| 亚洲主播在线播放| 亚洲欧洲一区二区在线观看| 国产伦精品一区二区三区四区免费 | 欧美成人精品激情在线观看| 欧美调教视频| 欧美黄色成人网| 一区二区三区欧美在线观看| 国产精品激情| 久久夜精品va视频免费观看| 亚洲午夜国产一区99re久久| 欧美肥婆bbw| 香蕉成人啪国产精品视频综合网| 影音先锋亚洲精品| 国产伦理精品不卡| 欧美日韩午夜在线视频| 久热这里只精品99re8久| 午夜精品美女自拍福到在线| 亚洲福利精品| 久久国产主播| 亚洲欧美激情诱惑| 一本色道久久综合亚洲91|