亚洲人成网站在线播放2019 _日韩国产欧美精品_久久夜色精品国产欧美乱_在线视频福利一区

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

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


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

    D中有了專門(mén)用于標(biāo)識(shí)接口的關(guān)鍵字interface,而不用象C++中使用抽象類來(lái)代替。
    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項(xiàng)上。

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

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

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

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

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

    基于D的這個(gè)識(shí)別COM接口的方式,在dxpcom項(xiàng)目中,qiezi使用了別名的方式進(jìn)行了變換,既將dxpcom項(xiàng)目中的所有的接口名稱進(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;

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

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

    代碼一,無(wú)法通過(guò)運(yùn)行期斷言,因?yàn)榻涌贗Interface仍然為標(biāo)準(zhǔn)D接口,虛表的0項(xiàng)為ClassInfo指針無(wú)法被顯示的調(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)完全一致,卻能夠通過(guò)運(yùn)行時(shí)斷言的檢查。唯一的不同僅僅是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);  
}

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

 
更多信息請(qǐng)登陸http://61.191.27.74:802/ 最后,歡迎加入http://61.191.27.74:802/的會(huì)員


安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
亚洲人成网站在线播放2019 _日韩国产欧美精品_久久夜色精品国产欧美乱_在线视频福利一区
91久久国产婷婷一区二区| 国产精品日韩专区| 青青久久av北条麻妃黑人| 亚洲视频精品一区| 欧美精品www在线观看| 中文字幕精品一区日韩| 国产99午夜精品一区二区三区| 精品久久中出| 欧美精品亚州精品| 国产精品嫩草影院久久久| 国产精品激情av在线播放| 久久中文精品视频| 国产精品入口免费| 欧美成人亚洲成人日韩成人| 国产精品成av人在线视午夜片| 久久亚洲私人国产精品va| 欧美激情综合色| 亚洲伊人第一页| 日日骚一区二区网站| 欧美性猛交久久久乱大交小说| 国内精品久久影院| 成人a免费视频| 久久国产亚洲精品无码| 国产精品视频男人的天堂| 欧美激情精品久久久久久变态| 污视频在线免费观看一区二区三区 | 亚洲a∨日韩av高清在线观看| 天天综合中文字幕| 日韩暖暖在线视频| 欧美日韩一区二区三区在线观看免| 黄色一级片国产| 成人欧美一区二区三区黑人| 久久亚洲a v| 日韩视频免费在线| 九九热这里只有精品免费看| 天堂资源在线亚洲视频| 欧美韩国日本在线| 国产精品一区二区三区免费| 国产激情在线观看视频| 欧美精品性视频| 色噜噜一区二区| 国产一区免费视频| 久久av喷吹av高潮av| 蜜月aⅴ免费一区二区三区| 日本久久亚洲电影| 成人免费在线网| 国产精品欧美在线| 丁香六月激情婷婷| 国产日韩欧美视频在线| 久久精品人成| 一区二区三视频| 欧洲亚洲免费视频| 国产精品夜间视频香蕉| 日韩中文字幕在线精品| 亚洲欧美精品在线观看| 国产四区在线观看| 久久九九免费视频| 日韩成人在线资源| 99久久99久久精品| 精品国产一区三区| 欧美一区少妇| 91国产精品视频在线| 不用播放器成人网| 欧美精品123| 国产成人综合一区二区三区| 亚洲一二区在线| 国产欧美精品aaaaaa片| 国产精品免费久久久| 日韩免费一级视频| 久久人91精品久久久久久不卡| 久久久久久国产精品久久| 黄色一级视频在线播放| 日韩在线视频一区| 日本亚洲导航| 久久久最新网址| 亚洲乱码一区二区三区| 国产美女视频免费| 欧美成年人视频网站| 国产综合久久久久| 国产精品久久久久免费| 欧美日韩一区二区三区在线观看免| 久久久久久久久国产| 少妇高潮喷水久久久久久久久久| dy888夜精品国产专区| 久久久久久国产精品美女| 国产精品中文字幕在线| 欧美日韩高清区| 成人亚洲欧美一区二区三区| 中文字幕乱码一区二区三区| 国产伦理久久久| 永久久久久久| 99久久久精品免费观看国产| 亚洲精品天堂成人片av在线播放| 97国产精品久久| 天天在线免费视频| 国产成人精品999| 日本一区二区三区免费看| 国产高清自拍一区| 色中色综合成人| 国产v综合v亚洲欧美久久| 日本一区二区在线| 日日狠狠久久偷偷四色综合免费| 欧美在线播放cccc| 国产精品国产对白熟妇| 国产乱码精品一区二区三区卡 | 日韩在线观看成人| 欧美精品99久久| 久热精品视频在线观看一区| 国产精品永久免费在线| 性一交一乱一伧国产女士spa| 日韩亚洲综合在线| 激情久久av| 国产99视频在线观看| 91精品国产高清久久久久久91裸体 | 午夜精品美女自拍福到在线| 久久亚洲午夜电影| 日本精品久久久| 国产a级片网站| 欧美午夜小视频| 国产精品久久久久久久美男| 成人91免费视频| 日韩欧美精品一区二区| 国产精品国产亚洲精品看不卡 | 欧美有码在线视频| 欧美日本高清一区| 久章草在线视频| 精品欧美国产| 亚洲一区三区在线观看| 国产不卡一区二区在线播放| 欧美成人精品免费| 亚洲色图都市激情| 久久久国产影院| www.亚洲视频.com| 欧美性大战久久久久xxx| 欧美精品一二区| 久久免费视频观看| 好吊色欧美一区二区三区视频| 亚洲午夜精品久久| 国产精品涩涩涩视频网站| 97色伦亚洲国产| 黄色一级片av| 日韩av高清在线播放| 久久中文字幕国产| 久久人人九九| 国产熟人av一二三区| 日韩精品一区在线视频| 亚洲字幕在线观看| 国产精品久久久av| 久久综合狠狠综合久久综青草| 免费精品视频一区二区三区| 日本精品一区二区三区视频| 一区二区高清视频| 久久亚洲精品网站| www.日韩视频| 久久久久se| 不卡视频一区二区| 国产在线观看欧美| 欧美专区第一页| 天堂精品一区二区三区| 久久夜色精品国产| 久久久成人精品| 久久精品国产sm调教网站演员| 苍井空浴缸大战猛男120分钟| 国精产品99永久一区一区| 日本不卡久久| 午夜精品蜜臀一区二区三区免费| 久久91亚洲精品中文字幕| 国产精品视频久| 日韩在线中文字幕| 久久精品视频16| 国产精品91久久久| 91九色蝌蚪成人| 不卡一区二区三区视频| 国产精品一区二区三区毛片淫片| 欧美精品国产精品久久久| 青青成人在线| 日韩欧美一区二区三区四区 | 日本人妻伦在线中文字幕| 亚洲一区亚洲二区| 欧美激情综合亚洲一二区| 国产精品久久久久久久av电影| 久久精品视频免费播放| 久久久精品视频成人| 亚洲蜜桃av| 亚洲免费av网| 亚洲一区二区三区四区中文| 亚洲一区不卡在线| 久久国产精品偷| 欧美精品日韩三级| 九九精品在线观看| 国产av国片精品| 亚洲自拍的二区三区| 亚洲精品视频一二三| 色阁综合av| 日韩精品一区二区三区电影| 日本久久久网站| 欧美在线视频一区| 男女午夜激情视频| 国产在线精品一区| 国产主播喷水一区二区|