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

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

常用鏈接

留言簿(10)

隨筆分類

隨筆檔案

連接資料

最新隨筆

搜索

  •  

最新隨筆

最新評論

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

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

  場景一:在.NET中調用WindowsAPI或DLL。

  這是比較普遍的需求。一般來說,簡單的函數調用,大可直接用C#/VB.NET,經過DllImport屬性包裝出函數來調用。如:

[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用到的人實在是多,因此有一個專門的wiki站點,收集這方面的資料:http://www.pinvoke.net/,對于常用的函數甚至有完整的應用例子和幫助。當然,如果你有相應的資料和例子,你也可以貢獻你的力量,給其它人幫助。

  場景二:用托管C++包裝現有的DLL,供C#調用

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

  仍以MoveFile為例吧,這樣比較簡單:


#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文件,就可以直接調用了:
wrapper.ApiWrapper.MoveFile(@"c:\debug.log", @"c:\debug.txt");
  假如原有的代碼是基于COM的,那么太好了,VisualStudio等IDE會自動生成一個用于包裝的dll,供你調用。當然因特殊需要而手工編碼的是另一回事。

  場景三:現有C++原代碼,包裝后供C#調用。

  C++的原代碼,實際上可以直接編譯成托管代碼。MFC也好ATL也好……這樣看起來在.NET中最強大的編程語言就是C++了:它不僅可以編寫托管程序,甚至可以將標準C++的代碼也編譯成托管程序!其實VC++最強大的地方不止如此,它還在于能夠編寫混合了托管和非托管的代碼的程序!!!這樣最大的好處不僅可以將關鍵代碼直接編譯成非托管的代碼,還可以避免被反編譯。
  
  假設現有C++代碼如下:
class UnmanagedClass {
public:
     LPCWSTR GetPropertyA() { return L"Hello!"; }
     void MethodB( LPCWSTR ) {}
};  我們只要再增加一個包裝類到工程文件中: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;
     };
}
  然后,改變編譯選項為“使用公共語言擴展 /clr”就可以了。這樣,我們把代碼編譯成DLL文件就可以供.NET其它語言調用了。
  最后,C#中可以象如下的代碼一樣調用C++類了:ManagedClass mc = new ManagedClass();
mc.MethoB("Hello");
string s = mc.get_PropertyA;
  場景四:如何在托管C++代碼中混合托管和非托管代碼

  很簡單,只要從#pragma unmanaged編譯指示開始的程序,一率編譯成非托管代碼;要想恢復成托管代碼,只要使用#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 函數:[PreserveSig, MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType=MethodCodeType.Native), SuppressUnmanagedCodeSecurity]
public static unsafe void modopt(CallConvCdecl) f<char const *>(sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)*);  
  看不到源碼,而方法屬性標記為Unmanaged。
  如果沒有加上#pragma unmanaged,反編譯得到的 f 函數為: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);
}

  其中的函數內容一目了然。如果你的函數沒有調用operator等不好理解的類庫,那么反編譯出來的代碼簡直和源碼沒差別。

  場景五:不想要DLL,能不能直接把C++源代碼與C#源代碼一起編譯成一個單獨的Assembly呢?

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

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

  很簡單,你照樣用你的C++寫你的程序,然后測試沒有錯誤后,將編譯選項改為/clr,好了,Rebuild,你的程序現在是.NET了。

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

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

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

FeedBack:
# re: 您也使用托管C++嗎?[未登錄] 2008-08-15 19:08 ZZ
c++本身也變態,不要用托管的  回復  更多評論
  
# re: 您也使用托管C++嗎? 2008-08-17 17:48 dell筆記本
軟件的移植簡直是一種折磨,托管C++到很有趣  回復  更多評論
  
# re: 您也使用托管C++嗎? 2008-08-18 12:05 WINZHENG
我現在是用C#,但是CEO交給我了兩個VC的程序,讓我優化這個VC程序,我該從什么地方著手,謝謝  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              欧美另类一区| 亚洲欧美国产不卡| 亚洲精品乱码久久久久久按摩观| 久久亚洲影音av资源网| 欧美日韩第一页| 欧美激情第二页| 欧美区国产区| 国产精品久久久爽爽爽麻豆色哟哟| 欧美日韩高清区| 欧美日韩一区二区三区在线看| 欧美日韩免费看| 国产欧美大片| 亚洲激情视频在线| 亚洲免费黄色| 欧美在线播放高清精品| 久久躁狠狠躁夜夜爽| 亚洲电影在线看| 99ri日韩精品视频| 欧美一乱一性一交一视频| 久久综合婷婷| 国产精品美女午夜av| 在线不卡亚洲| 亚洲午夜精品国产| 美国十次了思思久久精品导航| 亚洲第一页自拍| 亚洲视频二区| 你懂的国产精品| 国产欧美亚洲一区| 日韩亚洲视频| 久久一区二区三区国产精品| 亚洲精品视频啊美女在线直播| 亚洲欧美成人一区二区三区| 欧美激情按摩| 亚洲大胆人体视频| 久久av最新网址| 99精品久久免费看蜜臀剧情介绍| 久久久亚洲高清| 国产美女精品视频| 一区二区三区欧美在线| 麻豆国产va免费精品高清在线| av不卡在线| 欧美噜噜久久久xxx| 亚洲国产精品ⅴa在线观看| 久久国产欧美日韩精品| 99视频超级精品| 久久综合久久综合久久| 国产日韩在线不卡| 午夜伦理片一区| 日韩亚洲欧美成人| 欧美成人精品三级在线观看| 一区视频在线看| 久久九九99| 午夜老司机精品| 国产精品v亚洲精品v日韩精品 | 久久亚洲捆绑美女| 欧美日韩日本国产亚洲在线| 亚洲欧洲综合另类| 欧美 日韩 国产在线| 欧美中文字幕在线播放| 亚洲综合国产精品| 欧美日韩精品是欧美日韩精品| 亚洲国产国产亚洲一二三| 亚洲国产精彩中文乱码av在线播放| 一本久久a久久精品亚洲| 免费人成网站在线观看欧美高清| 国产精品一区二区女厕厕| 一区二区三区视频观看| 亚洲日本中文字幕| 欧美高清影院| 99re6这里只有精品| 欧美高清视频在线播放| 久久婷婷亚洲| 亚洲三级免费观看| 亚洲国产日韩一级| 欧美人与性动交a欧美精品| 亚洲蜜桃精久久久久久久| 亚洲国产你懂的| 欧美激情一区二区三区全黄| 亚洲靠逼com| 日韩一区二区精品葵司在线| 欧美亚洲成人免费| 久久精品2019中文字幕| 久久久xxx| 亚洲日本aⅴ片在线观看香蕉| 亚洲国产精品一区二区第一页| 欧美激情一区二区三区| 亚洲国产成人av好男人在线观看| 亚洲国产欧美另类丝袜| 欧美色道久久88综合亚洲精品| 亚洲欧美日韩在线一区| 久久精品国产91精品亚洲| 最新中文字幕一区二区三区| 99天天综合性| 伊人天天综合| 一区二区三区国产精品| 韩国在线视频一区| 亚洲国产成人av| 国产嫩草影院久久久久 | 欧美一乱一性一交一视频| 有坂深雪在线一区| 日韩视频在线一区| 韩国一区二区三区美女美女秀| 亚洲精品国精品久久99热| 国产精品一区二区男女羞羞无遮挡| 麻豆精品视频| 国产精品一香蕉国产线看观看| 欧美成人激情视频| 欧美日韩亚洲一区| 欧美成人中文字幕| 国产伦一区二区三区色一情| 欧美激情一区二区三区蜜桃视频 | 午夜久久久久久久久久一区二区| 欧美一区二区视频在线观看2020 | 国产精品久久久久久久9999| 牛牛国产精品| 国产视频一区二区在线观看 | 欧美一级视频一区二区| 一区二区三区四区国产| 美日韩免费视频| 久久久精品国产99久久精品芒果| 欧美午夜欧美| 91久久久久久久久久久久久| 国模套图日韩精品一区二区| 亚洲一区免费观看| 亚洲一区免费视频| 欧美理论电影在线观看| 久久综合伊人77777| 国产日本欧美视频| 亚洲少妇中出一区| 亚洲精品字幕| 欧美高清影院| 亚洲国产日韩欧美在线99| 亚洲国产精品成人| 久久免费偷拍视频| 免费看的黄色欧美网站| 怡红院精品视频| 久色婷婷小香蕉久久| 久久综合伊人77777尤物| 国内成人自拍视频| 久久高清国产| 欧美成人dvd在线视频| 亚洲国产综合在线| 女生裸体视频一区二区三区| 嫩模写真一区二区三区三州| 黄色成人在线| 玖玖精品视频| 亚洲日本欧美| 亚洲一区二区三区在线观看视频| 欧美日韩麻豆| 亚洲免费视频在线观看| 久久国产99| 一区二区在线视频观看| 美女性感视频久久久| 亚洲第一二三四五区| 日韩亚洲欧美成人| 国产精品一香蕉国产线看观看 | 午夜亚洲视频| 老色批av在线精品| 亚洲人精品午夜| 国产精品久久福利| 欧美一区二区视频在线| 欧美国产国产综合| 亚洲一区二区免费看| 国产日韩欧美一区在线| 美女精品自拍一二三四| 9色精品在线| 裸体歌舞表演一区二区| 一区二区三区视频在线播放| 国产精品一区久久久| 久久综合色影院| 亚洲一区二区不卡免费| 欧美电影免费观看| 久久精品二区| 亚洲欧洲在线一区| 国产精品二区三区四区| 久久久精品动漫| 99视频日韩| 欧美激情国产高清| 午夜视频一区二区| 亚洲欧洲一级| 国产一区二区剧情av在线| 欧美激情中文不卡| 欧美一区亚洲| 99成人免费视频| 欧美国产日产韩国视频| 亚洲欧美在线网| 亚洲美洲欧洲综合国产一区| 国产综合久久久久久鬼色| 欧美视频网址| 欧美高清影院| 久久综合久色欧美综合狠狠| 性欧美在线看片a免费观看| 一本久久青青| 亚洲国产精品久久| 免费视频亚洲| 久久国产精品第一页| 亚洲欧美区自拍先锋| 一区二区欧美精品| 亚洲精品一区二区网址| 亚洲成人直播|