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

隨筆 - 67  文章 - 171  trackbacks - 0
<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

常用鏈接

留言簿(10)

隨筆分類

隨筆檔案

連接資料

最新隨筆

搜索

  •  

最新隨筆

最新評(píng)論

您也使用托管C++嗎?
  轉(zhuǎn)向.NET后,手頭上往往仍有舊的模塊要重用。也許這些模塊是Delphi寫的,也許是C/C++寫的,或者是其它編程語(yǔ)言……為了能把它們移植到.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)大的編程語(yǔ)言就是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)為“使用公共語(yǔ)言擴(kuò)展 /clr”就可以了。這樣,我們把代碼編譯成DLL文件就可以供.NET其它語(yǔ)言調(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等不好理解的類庫(kù),那么反編譯出來的代碼簡(jiǎn)直和源碼沒差別。

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

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

  開心一刻:我只會(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ù)。

posted on 2008-08-15 16:36 cpsprogramer 閱讀(5121) 評(píng)論(3)  編輯 收藏 引用 所屬分類: VC++

FeedBack:
# re: 您也使用托管C++嗎?[未登錄] 2008-08-15 19:08 ZZ
c++本身也變態(tài),不要用托管的  回復(fù)  更多評(píng)論
  
# re: 您也使用托管C++嗎? 2008-08-17 17:48 dell筆記本
軟件的移植簡(jiǎn)直是一種折磨,托管C++到很有趣  回復(fù)  更多評(píng)論
  
# re: 您也使用托管C++嗎? 2008-08-18 12:05 WINZHENG
我現(xiàn)在是用C#,但是CEO交給我了兩個(gè)VC的程序,讓我優(yōu)化這個(gè)VC程序,我該從什么地方著手,謝謝  回復(fù)  更多評(píng)論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              亚洲六月丁香色婷婷综合久久| 国产亚洲激情视频在线| 亚洲黄色免费电影| 亚洲国产精品成人| 欧美女同在线视频| 一区二区三区国产精品| 亚洲一二三区视频在线观看| 国产精品无人区| 久久久久久夜| 欧美18av| 亚洲欧美精品在线观看| 午夜欧美电影在线观看| 亚洲福利视频网站| 亚洲免费电影在线| 国产日产高清欧美一区二区三区| 麻豆精品一区二区av白丝在线| 免费看精品久久片| 亚洲欧美国产视频| 久久乐国产精品| 在线视频精品一区| 欧美制服丝袜| 一本大道久久a久久综合婷婷| 亚洲一区免费在线观看| 亚洲第一区在线观看| 一区二区三区你懂的| 国产一区二区三区电影在线观看| 你懂的国产精品永久在线| 欧美日韩精品免费| 久久久久九九视频| 欧美日韩在线另类| 欧美gay视频| 国产精品成人免费视频 | 欧美视频一二三区| 国产精品成人v| 99精品国产99久久久久久福利| 一区二区三区黄色| 影音先锋亚洲电影| 亚洲伊人第一页| 亚洲美女在线国产| 久久久www成人免费精品| 在线性视频日韩欧美| 久久中文精品| 久久精品国产69国产精品亚洲 | 99这里有精品| 亚洲人成网在线播放| 久久九九99视频| 欧美一区二区三区视频| 欧美精品尤物在线| 欧美成人在线免费观看| 国产亚洲精久久久久久| 亚洲视频精品在线| 亚洲天堂免费在线观看视频| 美日韩丰满少妇在线观看| 久久久久久夜| 国产三区精品| 亚洲欧美日韩在线| 亚洲欧美日韩视频一区| 欧美人与禽猛交乱配视频| 女女同性女同一区二区三区91| 国内精品久久国产| 欧美一区二区视频观看视频| 亚洲欧美日韩成人| 国产精品久久91| 亚洲午夜高清视频| 亚洲主播在线观看| 国产精品日韩欧美一区二区三区 | 91久久综合| 亚洲精选国产| 欧美日韩国产精品一卡| 亚洲精品综合精品自拍| 夜夜精品视频一区二区| 欧美日韩不卡| 宅男噜噜噜66国产日韩在线观看| 亚洲性夜色噜噜噜7777| 国产精品久久一卡二卡| 亚洲欧美日韩国产中文| 久久精品综合网| 一区二区三区在线视频观看| 麻豆国产精品777777在线| 亚洲缚视频在线观看| 一本色道久久综合狠狠躁的推荐| 欧美日韩免费在线| 亚洲欧美视频| 欧美不卡视频一区发布| 999在线观看精品免费不卡网站| 欧美日韩网站| 亚洲欧美日韩成人| 免费成人高清| 一区二区冒白浆视频| 国产精品手机视频| 久久视频免费观看| 亚洲免费成人| 久久久久综合| 一区二区三区黄色| 国语自产偷拍精品视频偷| 毛片基地黄久久久久久天堂| 日韩亚洲成人av在线| 久久国产高清| 亚洲高清网站| 狠狠综合久久av一区二区老牛| 老鸭窝毛片一区二区三区| 亚洲精品在线视频观看| 欧美与欧洲交xxxx免费观看| 亚洲电影第三页| 国产精品黄视频| 久久综合给合| 亚洲免费伊人电影在线观看av| 蜜臀a∨国产成人精品| 在线亚洲一区二区| 在线成人av.com| 欧美午夜精品久久久久久浪潮| 久久激情一区| 亚洲欧美精品一区| 亚洲裸体在线观看| 久色婷婷小香蕉久久| 亚洲欧洲av一区二区| 亚洲看片免费| 精品成人一区二区| 国产精品有限公司| 欧美激情精品久久久久久免费印度| 欧美亚洲在线| 一本久道综合久久精品| 欧美激情在线观看| 久久久精品动漫| 亚洲在线观看免费视频| 亚洲精品国产拍免费91在线| 经典三级久久| 国产亚洲欧美aaaa| 国产精品伊人日日| 欧美色综合天天久久综合精品| 免费91麻豆精品国产自产在线观看| 亚久久调教视频| 亚洲桃花岛网站| 一区二区激情小说| 亚洲美女视频网| 亚洲成人自拍视频| 免费一级欧美片在线观看| 性欧美8khd高清极品| 亚洲欧美日韩中文视频| 亚洲一区二区三区精品动漫| av72成人在线| 一区二区av| 亚洲视频在线观看| 亚洲一卡二卡三卡四卡五卡| 99re6这里只有精品| 日韩午夜电影| 亚洲影院免费观看| 午夜视频一区| 久久国产欧美日韩精品| 欧美在线视频一区二区三区| 久久精品女人| 久久免费高清| 欧美成人高清视频| 亚洲国产天堂久久国产91| 亚洲黄网站黄| 99视频+国产日韩欧美| 亚洲深爱激情| 欧美一区在线看| 久久亚洲视频| 欧美激情影院| 欧美亚州一区二区三区| 国产伪娘ts一区| 亚洲国产精品福利| 一道本一区二区| 欧美有码视频| 蜜桃久久精品乱码一区二区| 亚洲国产另类久久精品| 一二三区精品| 欧美一区二区视频在线观看2020| 久久久精品网| 欧美精品三区| 国产日韩欧美不卡| 亚洲人精品午夜在线观看| 99亚洲伊人久久精品影院红桃| 亚洲欧美一级二级三级| 久久综合亚州| 99精品视频一区| 久久9热精品视频| 欧美日本一区二区高清播放视频| 销魂美女一区二区三区视频在线| 日韩一本二本av| 香蕉成人啪国产精品视频综合网| 麻豆免费精品视频| 欧美性猛交xxxx乱大交蜜桃| 激情亚洲网站| 午夜激情久久久| 亚洲国产精品99久久久久久久久| 亚洲一卡二卡三卡四卡五卡| 美女视频网站黄色亚洲| 国产精品99一区二区| 亚洲激情不卡| 久久久久国色av免费观看性色| 99精品视频免费观看视频| 久久这里有精品视频| 国产精品色一区二区三区| 亚洲精品国产精品国自产观看| 久久久九九九九| 亚洲一级片在线观看| 欧美大片在线观看一区| 狠狠色狠色综合曰曰|