好男人天堂网,久久精品国产这里是免费,国产精品成人一区二区,男人天堂网2021,男人的天堂在线观看,丁香六月综合激情

當(dāng)前位置:首頁 > 網(wǎng)站舊欄目 > 學(xué)習(xí)園地 > 設(shè)計軟件教程 > 深入分析D語言接口與COM接口的關(guān)系

深入分析D語言接口與COM接口的關(guān)系
2010-01-13 21:04:58  作者:佚名  來源:


深入分析D語言接口與COM接口的關(guān)系
   
    前兩天為了解決dxpcom項目中遇到的xpcom接口兼容性問題,看了一下DMD編譯器的源碼,對D的接口有了一些了解,現(xiàn)在總結(jié)出來,備忘。

    D中有了專門用于標(biāo)識接口的關(guān)鍵字interface,而不用象C++中使用抽象類來代替。
    D代碼:
Java代碼
interface ITest  
{  
int test();  

interface ITest
{
int test();
}
    C++代碼:
Java代碼
class ITest  
{  
int test()=0;  

class ITest
{
int test()=0;
}

    而D中的接口與C++中的接口不同之處是,D中的接口仍然含有ClassInfo,存放在虛表的0項上。

    從DMD的源碼中可以得知,D中的類,接口都在虛表的0項上保存了ClassInfo指針。
    這樣,D中的接口是無法與C++接口兼容的,則D就無法調(diào)用Windows的COM對象,至少是無法“優(yōu)雅”的調(diào)用(仍然可以使用struct進(jìn)行二進(jìn)制兼容代替)。

    為了解決這個問題,DMD就需要能夠表示出與C++兼容的COM接口,即需要一個虛表是"干凈"的接口。又由于,從一個COM接口繼承的接口仍然是一個COM接口,而COM模型的實(shí)現(xiàn)上又恰好定義了一個“IUnknown”根接口(COM體系中的所有的接口都是繼承了IUnknown)。

    所以,出于簡單實(shí)現(xiàn)的原則,DMD區(qū)分一個接口是D接口還是COM接口,關(guān)鍵就是判斷這個接口是不是叫做IUnknown,以及這個接口是否繼承自IUnknown,雖然接口都是通過Interface關(guān)鍵字聲明。更有趣的是,DMD僅僅判斷接口的名字是否為"IUnknown"而根本不管接口中的方法如何定義。

    以上所述內(nèi)容在進(jìn)行Windows COM編程時,幾乎不會被察覺,因為Windows的所有接口都是繼承自IUnknown,只要正常使用就可以了。

    而在進(jìn)行Mozilla xpcom編程的時候,xpcom的根接口叫做ISupports,DMD根本就不會認(rèn)為這是需要編譯為C++兼容的COM接口,而仍然會將虛表的0項進(jìn)行保留,結(jié)果給使用者造成了虛表指針偏移了的印象。

    基于D的這個識別COM接口的方式,在dxpcom項目中,qiezi使用了別名的方式進(jìn)行了變換,既將dxpcom項目中的所有的接口名稱進(jìn)行了優(yōu)雅的統(tǒng)一,又能夠使DMD生成正確的COM接口:
Java代碼
extern(Windows)  
interface IUnknown {  
  static const char[] IID_STR = NS_ISUPPORTS_IID_STR;  
  static const nsIID IID = NS_ISUPPORTS_IID;  
 
  /* void QueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */ 
  nsresult QueryInterface(nsIID * uuid, void * *result);  
 
  /* [noscript, notxpcom] nsrefcnt AddRef (); */ 
  nsrefcnt AddRef();  
 
  /* [noscript, notxpcom] nsrefcnt Release (); */ 
  nsrefcnt Release();  
 
}  
 
alias IUnknown nsISupports; 

extern(Windows)
interface IUnknown {
  static const char[] IID_STR = NS_ISUPPORTS_IID_STR;
  static const nsIID IID = NS_ISUPPORTS_IID;

  /* void QueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
  nsresult QueryInterface(nsIID * uuid, void * *result);

  /* [noscript, notxpcom] nsrefcnt AddRef (); */
  nsrefcnt AddRef();

  /* [noscript, notxpcom] nsrefcnt Release (); */
  nsrefcnt Release();

}

alias IUnknown nsISupports;

   這個現(xiàn)象同時也很好的說明了,D中的別名(alias)在符號的處理方面僅僅是一個符號的替換,同C/C++中的#define的作用相同。

    下面的兩段代碼就能很好的詮釋本文的內(nèi)容(感謝qiezi提供)

    代碼一,無法通過運(yùn)行期斷言,因為接口IInterface仍然為標(biāo)準(zhǔn)D接口,虛表的0項為ClassInfo指針無法被顯示的調(diào)用,在執(zhí)行的結(jié)果中就表現(xiàn)為虛表進(jìn)行了偏移。
Java代碼
extern(Windows):     
int test1(IInterface p)     
{     
    return 1;     
}     
    
int test2(IInterface p)     
{     
    return 2;     
}     
    
int test3(IInterface p)     
{     
    return 3;     
}     
    
struct InterfaceVtbl     
{     
extern(Windows):     
    int function(IInterface) test1;     
    int function(IInterface) test2;     
    int function(IInterface) test3;     
}     
    
struct Interface     
{     
    InterfaceVtbl* vtbl;     
    
    InterfaceVtbl vtbl_;     
    
    static Interface opCall()     
    {     
        Interface res;     
        res.vtbl_.test1 = &test1;     
        res.vtbl_.test2 = &test2;     
        res.vtbl_.test3 = &test3;     
        res.vtbl = &res.vtbl_;     
        return res;     
    }     
}     
    
interface IInterface     
{     
    int test1();     
    int test2();     
    int test3();     
}     
    
extern (D):     
    
void main()     
{     
    Interface i = Interface();     
    assert(i.vtbl.test1(cast(IInterface)&i) == 1);     
    assert(i.vtbl.test2(cast(IInterface)&i) == 2);     
    assert(i.vtbl.test3(cast(IInterface)&i) == 3);     
    
    IInterface ii = cast(IInterface)&i;     
    assert(ii.test1() == 1);     
    assert(ii.test2() == 2);     
    assert(ii.test3() == 3);     

extern(Windows):  
int test1(IInterface p)  
{  
    return 1;  
}  
 
int test2(IInterface p)  
{  
    return 2;  
}  
 
int test3(IInterface p)  
{  
    return 3;  
}  
 
struct InterfaceVtbl  
{  
extern(Windows):  
    int function(IInterface) test1;  
    int function(IInterface) test2;  
    int function(IInterface) test3;  
}  
 
struct Interface  
{  
    InterfaceVtbl* vtbl;  
 
    InterfaceVtbl vtbl_;  
 
    static Interface opCall()  
    {  
        Interface res;  
        res.vtbl_.test1 = &test1;  
        res.vtbl_.test2 = &test2;  
        res.vtbl_.test3 = &test3;  
        res.vtbl = &res.vtbl_;  
        return res;  
    }  
}  
 
interface IInterface  
{  
    int test1();  
    int test2();  
    int test3();  
}  
 
extern (D):  
 
void main()  
{  
    Interface i = Interface();  
    assert(i.vtbl.test1(cast(IInterface)&i) == 1);  
    assert(i.vtbl.test2(cast(IInterface)&i) == 2);  
    assert(i.vtbl.test3(cast(IInterface)&i) == 3);  
 
    IInterface ii = cast(IInterface)&i;  
    assert(ii.test1() == 1);  
    assert(ii.test2() == 2);  
    assert(ii.test3() == 3);  
}

    代碼二,與代碼一的結(jié)構(gòu)完全一致,卻能夠通過運(yùn)行時斷言的檢查。唯一的不同僅僅是IInterface的名字換成了IUnknown!!
Java代碼
extern(Windows):     
int test1(IUnknown p)     
{     
    return 1;     
}     
    
int test2(IUnknown p)     
{     
    return 2;     
}     
    
int test3(IUnknown p)     
{     
    return 3;     
}     
    
struct InterfaceVtbl     
{     
extern(Windows):     
    int function(IUnknown) test1;     
    int function(IUnknown) test2;     
    int function(IUnknown) test3;     
}     
    
struct Interface     
{     
    InterfaceVtbl* vtbl;     
    
    InterfaceVtbl vtbl_;     
    
    static Interface opCall()     
    {     
        Interface res;     
        res.vtbl_.test1 = &test1;     
        res.vtbl_.test2 = &test2;     
        res.vtbl_.test3 = &test3;     
        res.vtbl = &res.vtbl_;     
        return res;     
    }     
}     
    
interface IUnknown     
{     
    int test1();     
    int test2();     
    int test3();     
}     
    
extern (D):     
    
void main()     
{     
    Interface i = Interface();     
    assert(i.vtbl.test1(cast(IUnknown)&i) == 1);     
    assert(i.vtbl.test2(cast(IUnknown)&i) == 2);     
    assert(i.vtbl.test3(cast(IUnknown)&i) == 3);     
    
    IUnknown ii = cast(IUnknown)&i;     
    assert(ii.test1() == 1);     
    assert(ii.test2() == 2);     
    assert(ii.test3() == 3);     

extern(Windows):  
int test1(IUnknown p)  
{  
    return 1;  
}  
 
int test2(IUnknown p)  
{  
    return 2;  
}  
 
int test3(IUnknown p)  
{  
    return 3;  
}  
 
struct InterfaceVtbl  
{  
extern(Windows):  
    int function(IUnknown) test1;  
    int function(IUnknown) test2;  
    int function(IUnknown) test3;  
}  
 
struct Interface  
{  
    InterfaceVtbl* vtbl;  
 
    InterfaceVtbl vtbl_;  
 
    static Interface opCall()  
    {  
        Interface res;  
        res.vtbl_.test1 = &test1;  
        res.vtbl_.test2 = &test2;  
        res.vtbl_.test3 = &test3;  
        res.vtbl = &res.vtbl_;  
        return res;  
    }  
}  
 
interface IUnknown  
{  
    int test1();  
    int test2();  
    int test3();  
}  
 
extern (D):  
 
void main()  
{  
    Interface i = Interface();  
    assert(i.vtbl.test1(cast(IUnknown)&i) == 1);  
    assert(i.vtbl.test2(cast(IUnknown)&i) == 2);  
    assert(i.vtbl.test3(cast(IUnknown)&i) == 3);  
 
    IUnknown ii = cast(IUnknown)&i;  
    assert(ii.test1() == 1);  
    assert(ii.test2() == 2);  
    assert(ii.test3() == 3);  
}

    另外需要說明的是extern(D),extern(Windows),extern(Pascal)等特征,只是用來描述函數(shù)的調(diào)用約定,與接口的類型無關(guān)。
    一句話:D中的類與標(biāo)準(zhǔn)D接口都有ClassInfo在虛表的0項上,而COM接口的虛表是干凈的;而將一個接口聲明為COM接口的方式為:將這個接口命名為IUnknown或繼承自IUnknown。

 
更多信息請登陸http://61.191.27.74:802/ 最后,歡迎加入http://61.191.27.74:802/的會員


安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
青青久热| 久久精品大片| 青青久久精品国产免费看| 精品视频在线看 | 午夜欧美福利| 欧美另类videosbestsex久久| 久草免费在线色站| 国产一区免费观看| 日韩av东京社区男人的天堂| 人人干人人草| 国产网站免费视频| 日韩在线观看视频免费| 91麻豆精品国产自产在线| 成人影院久久久久久影院| 99热热久久| 国产网站在线| 四虎影视库| 日韩中文字幕在线观看视频| 超级乱淫黄漫画免费| 国产极品精频在线观看| 日本在线www| 四虎影视久久久免费| 精品国产香蕉在线播出 | 国产原创中文字幕| 亚洲天堂免费| 日本在线不卡视频| 色综合久久天天综线观看| 午夜精品国产自在现线拍| 美女免费毛片| 国产成人啪精品| 亚洲第一色在线| 91麻豆国产福利精品| 免费国产在线观看| 高清一级做a爱过程不卡视频| 国产一区免费观看| 亚欧成人毛片一区二区三区四区| 精品久久久久久影院免费| 国产高清视频免费观看| 精品国产一区二区三区久久久狼 | 亚洲精品影院久久久久久| 亚洲天堂一区二区三区四区| 天天色成人网| 久久国产精品自线拍免费| 日本伦理黄色大片在线观看网站| 美女免费毛片| 亚洲精品影院一区二区| 亚洲精品久久玖玖玖玖| 天天色成人网| 国产精品自拍在线观看| 日韩专区第一页| 九九精品影院| 欧美激情一区二区三区在线| 日韩中文字幕在线观看视频| 欧美一级视频免费| 精品毛片视频| 黄色免费三级| 精品国产一区二区三区久久久蜜臀| 精品视频免费观看| 麻豆网站在线看| 精品视频在线观看一区二区| 免费国产在线观看| 九九精品影院| 日韩在线观看网站| 日韩在线观看免费| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 国产国语对白一级毛片| 欧美1卡一卡二卡三新区| 精品视频在线看| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 国产精品自拍亚洲| 999精品影视在线观看| 欧美国产日韩精品| 精品在线视频播放| 精品久久久久久中文字幕2017| 99久久精品国产国产毛片| 亚洲精品影院| 久久福利影视| 91麻豆国产| 成人免费网站久久久| 欧美日本免费| 麻豆系列 在线视频| 国产韩国精品一区二区三区| 国产不卡精品一区二区三区| 日韩在线观看免费完整版视频| 国产网站免费在线观看| 青青青草影院 | 99久久精品费精品国产一区二区| 国产视频一区二区在线观看| 日本免费乱人伦在线观看 | 免费国产在线观看| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 成人在免费观看视频国产| 四虎影视库| 成人a级高清视频在线观看| 国产伦精品一区二区三区在线观看| 亚洲wwwwww| 可以免费在线看黄的网站| 免费国产在线观看| 国产91精品系列在线观看| 国产成人精品综合在线| 午夜激情视频在线播放| 一a一级片| 91麻豆精品国产自产在线观看一区| 成人免费网站久久久| 美女免费毛片| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 欧美日本国产| 精品国产亚洲一区二区三区| 欧美激情一区二区三区视频| 天天色色网| 精品国产三级a| 日韩欧美一二三区| 91麻豆国产| 日韩欧美一及在线播放| 免费一级生活片| 黄视频网站免费看| 日韩在线观看网站| 日日夜夜婷婷| 亚洲精品影院| 久久精品欧美一区二区| 国产网站免费视频| 久久精品大片| 国产网站免费视频| 一级女性全黄久久生活片| 日本乱中文字幕系列| 亚欧乱色一区二区三区| 国产成a人片在线观看视频| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 国产一区精品| 国产不卡高清在线观看视频| 精品国产亚洲一区二区三区| 国产综合成人观看在线| 日韩专区第一页| 免费国产在线观看| 九九热精品免费观看| 久久精品店| 亚洲爆爽| 日韩avdvd| 国产福利免费视频| 日本在线不卡免费视频一区| 99热精品在线| 久久成人性色生活片| 国产精品1024永久免费视频 | 精品视频在线观看免费| 久久久久久久网| 亚欧成人乱码一区二区| 亚欧成人乱码一区二区| 国产精品自拍一区| 高清一级毛片一本到免费观看| 深夜做爰性大片中文| 天天色色网| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 在线观看成人网 | 久草免费在线色站| 台湾毛片| 精品视频在线看| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 精品视频免费看| 国产精品1024永久免费视频| 国产不卡福利| 国产成人女人在线视频观看| 国产网站麻豆精品视频| 91麻豆精品国产自产在线观看一区| 91麻豆精品国产自产在线| 你懂的日韩| 欧美一级视| 日韩专区一区| 久久精品大片| 二级片在线观看| 欧美a级大片| 欧美日本国产| 亚洲天堂一区二区三区四区| 亚洲wwwwww| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 色综合久久天天综合| 国产综合成人观看在线| 亚欧乱色一区二区三区| 国产一区二区精品久久91| 深夜做爰性大片中文| 二级特黄绝大片免费视频大片| 高清一级毛片一本到免费观看| 91麻豆精品国产综合久久久| 欧美另类videosbestsex视频| 国产麻豆精品免费密入口| 欧美1卡一卡二卡三新区| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 亚洲第一视频在线播放| 午夜在线影院| 国产一区二区精品| 免费国产在线视频| 欧美日本韩国| 亚洲精品影院久久久久久| 久久99爰这里有精品国产| 国产精品1024永久免费视频| 色综合久久天天综合| 亚洲 欧美 成人日韩| 午夜在线观看视频免费 成人| 精品国产一区二区三区久久久狼 | 在线观看导航| a级黄色毛片免费播放视频|