组件开发【COM】查询IUnknow接口返回的指针一定是对象的指针吗?

Tishion 2011-09-04 01:44:16
有一个需求,已经得到一个对象的接口指针,要通过这个接口指针获取到该对象的地址。
有人给我提供了一种方法就是通过该接口调用Qureyinterface查询IUnknow接口返回的指针,返回的IUnknow指针一定是该对象的地址,但是在实际操作中发现大部分都可以成功,但是总是会出现一种情况,查询IUnknow返回的指针并不是该对象的指针,而是该对象的指针向后偏移了4个字节的的指针,就是说指向了第二个虚函数表指针。

其中所有的对象都是通过ATL开发出来的。

1.请问上述情况出现的原因是什么?对应于上一种产生偏移的那个对象的第一个虚函数表指针是哪个接口的??
2.如何通过任意接口获取到该对象的地址???

恳请熟悉ATL组件内存布局的同仁点拔一下!不胜感激!
...全文
197 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tishion 2011-09-08
  • 打赏
  • 举报
回复
无满意答案。结贴。
  • 打赏
  • 举报
回复
1 用 QureyInterface查询接口就行了
2 你不需要知道对象在哪里,完全可以用C语言写COM,直接访问全局变量,根本不存在对象。
Tishion 2011-09-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pathuang68 的回复:]
楼主别玩COM,M$自己都不怎么支持了。
[/Quote]

...好 搞完这个以后再也不玩了
Tishion 2011-09-05
  • 打赏
  • 举报
回复
COM组件所在的宿主(DLL)被加载之后,经过一系列函数调用,
最终调用DllGetClassObject( const CLSID & rclsid, const IID & riid, void ** ppv);创建该对象的类厂,例如该对象叫做 CXXObject,那么对应类厂叫做CXXObjectFactory,其中类厂实现了一个方法CreateInstance,该函数中真正的在堆中new出了对象。

HRESULT CXXObjectFactory::CreateInstance(IUnknow * pUnknowOuter, cons IID& iid, void ** ppv)
{
CXXObject * pObj;
HRESULT hr;

* ppv = NULL;
hr = E_OUTOFMEMORY;

if(pUnknowOuter != NULL;
return CLASS_E_NOAGGRATION;

pObj = new CXXObject; //这里的pObj就是所谓的对“象的地址”
if(pObj == NULL)
return hr;

hr = pObj->QuryInterface(iid, ppv);
if(hr != S_OK)
{
delete pObj;
}
}


一般来说 查询IUnknow时返回的都是实现的第一个接口经过statci_cast之后的值,所以一般来说查询IUnknow返回的就是对象的地址。
但是正如fanster28_所说,并没有要求一定要返回第一个接口,只是要求返回同一个值,所以就有可能返回的不是第一个接口转换的值,这样查询到的IUnknow就不为对象地址了。
头疼现在要怎么办。。。。
leer168 2011-09-05
  • 打赏
  • 举报
回复
让开发2年COM的情何以堪啊,表示不知道为什么,第一个unknown接口地址应该就是对象地址,55555555555555
maquan 2011-09-05
  • 打赏
  • 举报
回复
楼主要访问的 COM 对象,是自己实现的吗?如果是自己实现的,定义一个 Interface 来获取“对象地址”应该最正宗了。如果是别人实现的,这个嘛……原则上还是只访问 Interface 的好,无法保证你通过接口地址转换来的那个指针是否指向“对象”,说到底,人家都不一定是用 C++ 实现的。


————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
pathuang68 2011-09-04
  • 打赏
  • 举报
回复
楼主别玩COM,M$自己都不怎么支持了。
Tishion 2011-09-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fanster28_ 的回复:]
COM对于QueryInterface查询IUnknow返回指针是否对象地址并无保证,
QueryInterface都是类自己实现的,自然不能要求返回的指针是对象的地址。

COM只是规定了对所有的IUnkown接口的查询都必需返回相同的指针

主要是对实现多个接口的情况

class A : public Ix, public Iy

只需要保证返回的IUnknow要么都是Ix……
[/Quote]

楼上所言极是,只不过我不是为了开发COM,正是因为别人开发了这些COM,而我现在要做的就是在针对这些已经存在的COM来做些事情,只是不能看到源代码,COM的理论规范我认为我也略有熟悉,只是对于ATL实现的COM的跟理论规范有不少不同。

所以现在我遇到的问题就是 用ATL实现的COM组件的内存布局的所有形式。。
不过还是感谢你的解答,一般对象的第一个虚函数表指针都是指向QueryInterface(),AddRef()和Rrlease()三个函数的直接实现,而该对象中其他的接口的虚函数表中都是指向一个调整this指针值的Thunk,
然后是一条jmp指令跳转到该对象所实现的那三个函数。

我就是想得到这三个函数的地址。
fanster28_ 2011-09-04
  • 打赏
  • 举报
回复
COM对于QueryInterface查询IUnknow返回指针是否对象地址并无保证,
QueryInterface都是类自己实现的,自然不能要求返回的指针是对象的地址。

COM只是规定了对所有的IUnkown接口的查询都必需返回相同的指针

主要是对实现多个接口的情况

class A : public Ix, public Iy

只需要保证返回的IUnknow要么都是Ix里那个,要么都是Iy里那个即可

至于你说的偏移了4个字节的原因想必就是组件里对IUnknow的查询返回的是
*ppv = static_cast<Iy*>(this);

COM相比C++强调了接口继承的概念,如果确实需要利用对象指针做一些事,
应该实现一个接口去做,而非利用对IUnknow查询的结果。

COM新手,个人愚见,如有错误,望赐教。
Tishion 2011-09-04
  • 打赏
  • 举报
回复
木人愿意解释解释?
Tishion 2011-09-04
  • 打赏
  • 举报
回复
这个可以确定是in-process!
maquan 2011-09-04
  • 打赏
  • 举报
回复
对于 in-process 的还好说,如果是跨进程的,可能由于 proxy/stub 的关系,根本无法获取所谓的“对象指针”。不清楚楼主的需求背景是什么,也不好瞎出主意了,hehe
Tishion 2011-09-04
  • 打赏
  • 举报
回复
帮个忙吧。。。
Tishion 2011-09-04
  • 打赏
  • 举报
回复
在线等待大家解答。

64,640

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧