关于《com本质论》中的一些疑问(1)解决方案
关于《com本质论》中的一些疑问(1)
第一章还有两节看完,感觉这本书写的太好了,读起来觉得好有意思。但由于没有什么实践经验,有几个问问题想不通。希望大学指教
(1)书中第四页有如下代码
class _declspec(dllexport)FastString
{
char *m_psz;
public:
FastString(const char *psz);
~FastString(void);
int length(void) const;
int Find(const char *psz) const;
};
书上说dll发布商把上面的代码直接写到FastString.dll中,然后发布,当一个客户拿到这个dll后,在它自己的程序中如有以下程序段
......
loadLibrary( "FastString.dll ");
FastString myString( "hahahah ");
int length=myString.length();
......
按书上说的,如果客户自己的编绎器与编写这个dll的编绎器的名字改编方案不一样就会出现连接错误,这个有点想不通。我觉得客户的编绎器不可能改编FastString这个类中的成员函数吧,怎么会出错呢?难道是在执行myString.length();这句话时编绎器是把这个length()函数的名字进行了改编,还后到dll中去找?
(2)第20-21页
当为这个类增加一个新功能后,在接口类IFastString中增加一个实现此功能的纯虚函数FindN(),并在实现类FastString中来实现这个函数FindN()。书中有这么一句原话“当客户针对‘基于原先的接口定义编绎得到的对象’来调用FindN方法时,其结果显而易见,程序崩溃了”,这个非常的想不明白,“基于原先的接口定义编绎得到的对象”这个应该是用以前的DLL中的类定义的FastString对象吧,它怎么可能会调用FindN方法呢??那时的那个对象根本就没有FindN这个方法,怎么可能编绎出这样的对象呢?
真心希望大家给我讲讲,如果问题描述的不清楚,还请指出,谢谢了。
------解决方案--------------------
(1)C++编译器为了支持函数重载,会在最终生成的目标文件中改变函数的名字。也就是说,在最终的目标文件中,那个length函数名字并不是原来的“length”。否则,如果这个类中还有另外一个名为length的函数(这是C++所允许的),就不知道该如何对应了。
现在的问题就是:虽然编译器都会改写函数名字,但不同的编译器,甚至同一编译器的不同版本改写的具体规则可能不同,于是会造成问题。
(2)这个就是你钻牛角尖了。作者想说的就是:当你不小心混合使用老的dll和新的接口定义时,当然就“显然”要出问题了。
我记得这里还有上下文的,可惜偶的《COM本质论》被河马那厮给掳走了。:(
------解决方案--------------------
第一个C++为了实现函数重载,编译器会改变函数的名字,也就是通常所说的名字压延啦什么的;不同编译器使用的函数名改写规则是不一样的
第二个就是为了防止客户拿到了新的接口定义,但是客户在dll版本未升级的情况下以为自己的dll版本升级了,那样肯定会出问题了
ps:建议楼主先去看看《COM原理与应用》什么的书,比COM本质论可能简单点,个人觉的看COM本质论第一章都很费劲的话,后面会更看不懂!
第一章还有两节看完,感觉这本书写的太好了,读起来觉得好有意思。但由于没有什么实践经验,有几个问问题想不通。希望大学指教
(1)书中第四页有如下代码
class _declspec(dllexport)FastString
{
char *m_psz;
public:
FastString(const char *psz);
~FastString(void);
int length(void) const;
int Find(const char *psz) const;
};
书上说dll发布商把上面的代码直接写到FastString.dll中,然后发布,当一个客户拿到这个dll后,在它自己的程序中如有以下程序段
......
loadLibrary( "FastString.dll ");
FastString myString( "hahahah ");
int length=myString.length();
......
按书上说的,如果客户自己的编绎器与编写这个dll的编绎器的名字改编方案不一样就会出现连接错误,这个有点想不通。我觉得客户的编绎器不可能改编FastString这个类中的成员函数吧,怎么会出错呢?难道是在执行myString.length();这句话时编绎器是把这个length()函数的名字进行了改编,还后到dll中去找?
(2)第20-21页
当为这个类增加一个新功能后,在接口类IFastString中增加一个实现此功能的纯虚函数FindN(),并在实现类FastString中来实现这个函数FindN()。书中有这么一句原话“当客户针对‘基于原先的接口定义编绎得到的对象’来调用FindN方法时,其结果显而易见,程序崩溃了”,这个非常的想不明白,“基于原先的接口定义编绎得到的对象”这个应该是用以前的DLL中的类定义的FastString对象吧,它怎么可能会调用FindN方法呢??那时的那个对象根本就没有FindN这个方法,怎么可能编绎出这样的对象呢?
真心希望大家给我讲讲,如果问题描述的不清楚,还请指出,谢谢了。
------解决方案--------------------
(1)C++编译器为了支持函数重载,会在最终生成的目标文件中改变函数的名字。也就是说,在最终的目标文件中,那个length函数名字并不是原来的“length”。否则,如果这个类中还有另外一个名为length的函数(这是C++所允许的),就不知道该如何对应了。
现在的问题就是:虽然编译器都会改写函数名字,但不同的编译器,甚至同一编译器的不同版本改写的具体规则可能不同,于是会造成问题。
(2)这个就是你钻牛角尖了。作者想说的就是:当你不小心混合使用老的dll和新的接口定义时,当然就“显然”要出问题了。
我记得这里还有上下文的,可惜偶的《COM本质论》被河马那厮给掳走了。:(
------解决方案--------------------
第一个C++为了实现函数重载,编译器会改变函数的名字,也就是通常所说的名字压延啦什么的;不同编译器使用的函数名改写规则是不一样的
第二个就是为了防止客户拿到了新的接口定义,但是客户在dll版本未升级的情况下以为自己的dll版本升级了,那样肯定会出问题了
ps:建议楼主先去看看《COM原理与应用》什么的书,比COM本质论可能简单点,个人觉的看COM本质论第一章都很费劲的话,后面会更看不懂!