Chinaunix首页 | 论坛 | 博客
  • 博客访问: 313082
  • 博文数量: 174
  • 博客积分: 3061
  • 博客等级: 中校
  • 技术积分: 1740
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-04 22:43
文章分类

全部博文(174)

文章存档

2011年(54)

2010年(14)

2009年(30)

2008年(26)

2007年(27)

2006年(23)

我的朋友

分类: WINDOWS

2008-11-13 21:48:32

WWSDK Beta2 COM实现技术可行性分析

命题: .Net 能够实现为COM对象吗? C++/ATL开发的SDKCOM对象交互(互相调用)? 线程模型对实现有影响吗?COMSDK能够较方便的发布给.Net用户吗?

 

术语说明:

Clientcom.dll , 采用ATL编写的模拟SDk COM包装的COM对象,且是一个单件,且是一个MainSTA(这儿单件和线程模型的模式有待商榷)

aliim.exe , 它初始化了MainSTA

Dotnetcom.dll ,C# 编写的实现了ITestPlugin接口的COM对象.

Atlplugincom , 实现为Apart/Freecom组件。

 

说明:

1. 假定我们的Clientcom标记为MainSTA,创建于主线程, 因此它都运行于MainSTA。不过还是测试了它被在OtherSTA/MTA中创建的表现。

2. 对于套间的判定通过观察线程ID来辅助判断。

3. 插件被假定创建的线程等于Clientcom被创建的线程

 

Case 1: 观察dotnetcom 对象的线程模型,dotnet是否能够使用所有的线程模型?

结论:  还没有找到修改其线程模型的方式,通过修改注册从运行结果来看没有效果,从结果来看似乎dotnetcom始终被设置为both

 

Case 2 : dotnet可以实现COM接口,可以被回调/通知:

模拟dotnet COM对象实现ITestPlugin后当特定消息发生后得到通知.

前提: 由于aliim.exe 在进入后就call oleinitialize(NULL) 将自己带入了一个MAINSTA。因此测试中不再特别创建套间。

步骤:

1)    由于需要模拟一个合适的ATL COM wrapper ,因此在wwsdk.dll 初始化之后初始化 clientcom.dll.

2)    Aliim.exe call clientcom.dll::Test

3)    Clientcom.dll::Test 加载dotnetcom.dll 然后寻找ITestPlugin找到后调用OnNotify 来进行消息通知。

 

结论:

发现不管如何修改 ThreadingModel dotnetcom dll 始终在SameSTA中的到调用。

我还没有找到如何设置dotnetcom dll 如何成为Free/Single,仅仅修改注册表中的值没有达到类似的目的。根据我在forum MSDN上提问的回答,似乎认为在.Net编写的COM中注册表的值仅仅是个提示,可以认为就是等同于Both.

 

另外,通过重新写了一个atlplugincom.dll 编写为Free模式的组件,这样验证了,运行于Free模型下消息通知同样有效.

 

 

Clientcom(Create from MAINSTA)

Dotnetcom(Apartment)

Dotnetcom 运行于SAMESTAOk

atlplugincom  (Free)

atlplugincom  运行于MTAOk

atlplugincom  (Apartmemt)

Atlplugincom   运行于SAMESTAok

 

 

 

Clientcom(Create From Other STA)

Dotnetcom(Apartment)

Dotnetcom 运行于SAMESTAok

atlplugincom  (Free)

atlplugincom  运行于MTAok

Atlplugincom   (Apartmemt)

Atlplugincom   运行于SAMESTAok

 

 

Clientcom(Create From MTA)

Dotnetcom(Apartment)

Dotnetcom 运行于MainSTAok

atlplugincom  (Free)

atlplugincom  运行于MTAok

Atlplugincom   (Apartmemt)

Atlplugincom   运行于MainSTAok

 

Case 3 : dotnet COM对象可以调用ATL COM对象非UI,

模拟: dotnet COM 对象使用WWSDK COM Wrapper 对象的服务/方法.

前提: 由于aliim.exe 在进入后就call oleinitialize(NULL) 将自己带入了一个MAINSTA。因此测试中不再特别创建套间。

步骤:

1)    由于需要模拟一个合适的ATL COM wrapper ,因此在wwsdk.dll 初始化之后初始化 clientcom.dll.

2)    Aliim.exe call clientcom.dll::Test

3)    Clientcom.dll::Test 调用Dotnetcom::OnNotify

4)    Dotnetcom.dll OnNotify处理中调用clientcom.dll::Service方法。

 

结论: (clientcom 始终在MAINSTA)

 

Clientcom(MAINSTA)

Dotnetcom(Apartment)

Dotnetcom运行于SAMESTAok

Dotnetcom (OtherSTA)

Dotnetcom运行于OtherSTAok

Dotnetcom (MTA)

Dotnetcom 运行于MTA ok

 

 

Clientcom(Create from OtherSTA)

Dotnetcom(Apartment)

Dotnetcom运行于SAMESTAok

Dotnetcom  (OtherSTA)

Dotnetcom运行于OtherSTAok

Dotnetcom  (MTA)

Dotnetcom 运行于MTA ok

 

 

 

Clientcom(Create from MTA)

Dotnetcom(Apartment)

Dotnetcom运行于MainSTAok

Dotnetcom  (OtherSTA)

Dotnetcom运行于OtherSTAok

Dotnetcom  (MTA)

Dotnetcom 运行于MTA ok

 

 

Case 4 : dotnet COM对象可以调用ATL COM对象UI方法

模拟: dotnet COM 对象使用WWSDK COM Wrapper 对象的服务/方法.

前提: 由于aliim.exe 在进入后就call oleinitialize(NULL) 将自己带入了一个MAINSTA。因此测试中不再特别创建套间。

步骤:

5)    由于需要模拟一个合适的ATL COM wrapper ,因此在wwsdk.dll 初始化之后初始化 clientcom.dll.

6)    Aliim.exe call clientcom.dll::Test

7)    Clientcom::Test call dotnetcom::OnNotify

8)    Dotnetcom.dll OnNotify处理中调用clientcom.dll::Service方法。

 

结论: (clientcom 始终在MAINSTA)

 

Clientcom(Create from MAINSTA)

Dotnetcom(Apartment)

Dotnetcom运行于MAINSTAok

Dotnetcom (OtherSTA)

Dotnetcom运行于OtherSTAok

Dotnetcom  (MTA)

Dotnetcom 运行于MTAok

 

 

Clientcom(Create from OtherSTA)

Dotnetcom(Apartment)

Dotnetcom运行于SAMESTAok

Dotnetcom  (OtherSTA)

Dotnetcom运行于OtherSTAok

Dotnetcom  (MTA)

Dotnetcom 运行于MTAok

 

 

Clientcom(Create from MTA)

Dotnetcom(Apartment)

Dotnetcom运行于MAINSTAok

Dotnetcom  (OtherSTA)

Dotnetcom运行于OtherSTAok

Dotnetcom  (MTA)

Dotnetcom 运行于MTAok

 

Case 4 : clientcom对象作为SDK发布给.Net用户(这儿主要检验了C#)是否方便可行?

 

方式 : tlbimp 工具生成 interop binary 将此bianarycom dll 一起发布,经过更换机器测试通过。

 

结论:

1.    采用ATL 开发的COM对象能够调用C# 开发.Net COM对象,反之也行。

2.    线程模型并不妨碍我们开发的MainSTA对象与.Net / ATLCOM 的交互,尽管会带来可能存在的性能影响(这个不在评估之列)

3.    WWSDK(COM版本)可以通过随阿里旺旺捆绑发布的方式打包 interop.dll+sdk.dll 发布,而作为开发者安装阿里旺旺后就可以在C#环境下通过导入reference方式访问我们的SDK(这儿并没有评估.NetFramework 不同版本对我们发布的SDK是否有更多影响,本文测试了V2.0.50727)

 

潜在风险说明

1.    测试中没有找到如何设置dotnetcom Apartment属性方式。因此测试MTA模式是通过atl对象来替代。 (风险低)

2.    Wwsdk再发布给.Net plugin 开发者时候未评估不同版本.NetFramework对我们发布的interop对开发者的影响 .(风险中)

3.    未评估.Net 开发环境下除C#外的其他语言开发的组建同我们的wsdkcom交互。(风险中)

4.    采用类工厂单件模式能够避免实例反复创建,但是这个对象被用于不同套间时候存在问题,我们在编码的时候应该通过自定义单件模式解决(风险低)

 

尾声:

个人认为总体风险不高。

1.  .Net plugin交互中还存在一些可以提高的一些细节目前未明了,而这些细节的解决,将有助于另我们的WWSDK对于.Net开发者来说更加专业。

2.  从可行性来说,个人认为在规定的范围内(确定的某个.NetFramework 版本上,确定的几种.Net 语言比如C# )可行。

3.  由于时间较短,覆盖的面也有所限制,不能就各种技术细节进行更加深入地预言。

 

 

Question:

1.                    interop 发布时候用的.Netframework如何和实际运行及其上的.Netframework版本不一致是否有问题?

2.                    不同版本的interopdll存在于不同目录时候会否能够自动识别各自的interopdll.

3.                     多个.Netframework/runtime version 运行于aliim.exe中会否有问题?(不属于本次技术预言范畴)

 

 

第二次修订

Case 1 : 不同版本的interopdll存在于不同目录时候会否能够自动识别各自的interopdll.

 

结论: 我们可以将interopxxx.dll 打包发布到 aliim.exe 目录下,那么所有.Net 开发的插件在被加载的时候将优先使用aliim.exe同目录下的而不会使用插件自己目录下的,因此我们可以建议插件开发者根本不用发布他们自己的interopxxx.dll

Case 2 : 如果我们在某个版本发布了interopxxx.dll 比如它内部实际上包装了COM的一个对象一个方法. 然后过了一段时间我们发布了WWSDKCOM.dll 在某个对象上增加了一些方法,然后又增加了一个对象,同时更新发布了interopxx.dll 那么对于那些曾经使用老的interopxxx.dll 的插件能否兼容?

 

结论: ok.

 

Case 3: 如果我们仅仅通过一个CLSID以及一个.Net COM dll 我们在发布或者安装或者加载插件前如何确保这个.Net被正确注册? 然后可创建!

 

结论: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe complugin_1.dll /codebase , 将用于将.Net COM component 注册到注册表中,此后VC 客户端就可以通过registry 创建COM组件了. 在这个过程中实际上建议.Net 开发者提供StrongName .Net COM.

 

Case 4 : 随我们的阿里旺旺安装程序而提供的interop.wwsdk.dll 如果是用某个版本的.dotnetframe 工具生成的,那么对于.Net 开发者开发时候使用的不同.Netframework 版本有否影响? 对于最终运行时候会否有影响?

 

结论: 我采用了V1.1 SDK 带有tlbimp 生成interop.xxx.dll 在只有V2 .Netframework 的机器上运行没有问题.

阅读(777) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~