分享
 
 
 

关于C++/CLI中的Interop问题的思考

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

============================

在C++/CLI中如何让你的Managed Code和Unmanaged(Native) Code沟通自如?interior_ptr和pin_ptr是桥梁——interior_ptr充当一个Managed Heap上的Native Pointer的角色。而pin_ptr则可以把对象钉在Managed Heap上!

所以,pin_ptr允许把Managed世界里的东西带入Unmanaged(Native)世界。

而如果想反其道而行,即把Unmanaged(Native)世界里的东西带入Managed世界,则可以自己写一个ref/value class的wrapper(目前),以后微软打算允许Native Class在Managed Heap上创建,并且允许Ref Class在栈上创建(彼时ref class关键字是否还有存在的价值?),从而允许更为方便的交互。

但是这里的问题是,基本上这种交互都是处于“基本类型的数据”层次的交互。pin_ptr只能把基本类型钉在Managed Heap上,也就是说,你可以写:

pin_ptr<int> p = ...;

却不能写

pin_ptr<GC_Class> p = ...; //错误!

这是因为.NET的对象模型和Native C++的对象模型是不兼容的,即使可以把GC_Class的对象钉在GC堆上并返回其首地址,也不能把它作为一个Native Class类对象来用。反之亦然。

下面是关于这个问题的一些思考...很零碎:)

声明:这是和孟岩老师一次email内容的整理。请不要转载

===========================

孟老师,昨天我们聊到的关于Managed和Unmanaged代码如何在对象层面沟通问题,我后来想了一下,还和我的一个朋友讨论了许久,我的看法是这样的:

您记得.NET&COM Interopration吗?它面对的不正是Native类和Managed类的对象模型的不一致的问题吗?那它是怎么解决的呢?用Wrapper——如果要在COM (对应于我们说的Native Code)中调用.NET的类提供的服务,CLR运行层会负责为.NET对象创建一个Wrapper,这个Wrapper仅仅是个proxy,充当虚函数转发器,由于CLR可以通过查询元数据得知.NET类的一切信息,所以创建一个Wrapper非常容易。而在.NET中如何调用传统的COM服务呢?同样也是Wrapper,不过由于COM是编译后的Native Code,失去了类型信息,所以需要用户把IDL拿来再用.NET的编译器编译一次,以提供必要的元数据,这样CLR在运行期就可以轻松的创建Wrapper了。

也就是说,Wrapper充当了两种对象模型之间的协调者的作用。而这个Wrapper也只能由CLR来创建,因为CLR够底层,知道关于对象模型的一切细节。要在语言层面做这样一个Wrapper是肯定会失败的。所以,如果我记得不错的话,.NET的BCl里面是提供了Interop服务的——我记得有一个名字空间就叫InteropService。

同样,转到C++/CLI中,很显然,这里的矛盾在于对象模型之间的冲突。

再深一层想,这种冲突到底是不是本质上的?其实不是,关键是Native世界侧重效率,所以对象模型实现比较高效紧凑,而.NET的动态对象模型则需要有完善的运行时信息,所以对象就背了个大包:-)但是,虽然只是因为目的不同,而并非本质上的冲突,但是却实际上是很难调和的——你没有办法让Native Class的对象模型变得和.NET的对象模型一样(那样它就不是Native Class了),你更没有办法让.NET的对象模型变得和Native Class一样(那以为着丧失运行期的动态类型信息)。

那么,这么说来,问题的本质已经出现了——对象模型的理念不同,导致了它们之间的实现细节不同,而这种细节上的不同又导致了互操作的困难。几乎可以肯定的说,这里只要出现对象级别的互操作,就肯定需要某种转换机制,.NET&COM Interop使用的Wrapper就是其一。

但是,毕竟,.NET&COM Interop只是个库的实现。在语言层面,你仍然没有办法法把“^”转型为“*”(或者反过来)!这就使语言层面的对象级交互不那么trivial。到底有没有一个比.NET&COM Interop更好的方案呢?

下面就是我想的结果——

考虑Native Class和Ref Class的内存布局,显然Native Class的布局非常Naive,而Ref Class中除了和Native Class布局相似的部分之外,还有很多其它的附加信息如同步块,对元数据的引用,甚至GC信息。是不是可以这样想——通过合理安排Ref Class的二进制格局,可以使它在二进制格局上成为Native Class的二进制格局的一个超集,从而把Ref Class的实例的某个offset处的地址传给Native接口可以把它“当成”Native Class来用?

但是这种办法也只是想想而已,真正实现估计还会有更多的细节。另外,如果反过来,却不可能把Native Class“当成”Ref Class来用,因为它的虚函数表中的信息不够,这时候,是不是可以通过一个“廉价的”(who knows?:-))类似Box的操作把Native 对象中的vptr所指向的vtbl扩充成一个first class的method table?这样就可以“当成”.NET类来用了。

如果底层的细节的差异不是那么严重的话,这种方式还是可行的(who knows?:-)),这种方法的好处是没有引入中间层,所以比较轻量级。这就为语言层面的对象级交互提供了方便而高效的途径——为什么这么说呢?因为在目前,如果允许pin_ptr定住一个.net class并将它传给Native接口的话,无非要用类似于.NET&COM Interop的Wrapper方法来解决对象模型的差异问题,这是个昂贵的操作,而且更为重要的问题在于,即使创建了Wrapper,问题仍然没有解决,收到Wrapper的Native接口只能通过虚调用来调用Wrapper的方法,而没法像看起来的那样直接访问ref class的成员(Wrapper只有接口,而没有实现)。这就使pin_ptr的语义变掉了(Native程序员可以想象拥有一个指针却不能访问它所指向的对象的成员吗(假设是public的)?)。

但是,如果采用我上面“臆想”的办法,就可以进行轻量级的Interop,并且由于这种方法没有引入中间层,所以指针的语义可以得到保证。这样就只要对pin_ptr的语义进行一个扩展(使它可以指向Ref Class实例)就行了:-)

耽误老师时间了:-)只是一通臆想而已。老师有什么金砖银砖还望不要吝啬的砸过来哦,呵呵:-)

另外,我一直在讨论如何实现这个交互的问题,而并没有深入去思考“到底我们需不需要”这种对象级交互。我个人的一点浅的看法是:Managed和Unmanaged间的对象级交互主要是为了保证整个程序的结构性(整个程序能有一个OO架构),如果在两个世界的衔接点上愿意抛弃这种结构,我们的程序仍然还是可以活的很好,从本质上说,所有类最终都归结为基本类型,所以pin_ptr就能胜任了。没有“必要”的需求说我们一定要在两个世界的衔接点上维持OO架构。关于这个问题的严重性我没有直观的认识,因为没有实践经验,老师有什么看法赶快告诉我吧:-)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有