DLL中调用CoCreateInstance问题

cppzhentan 2011-10-05 04:33:32
在MyDll项目中的DllMain调用CoCreateInstance创建COM组件对象实例,一直返回E_NOINTERFACE,而在EXE项目中调用CoCreateInstance则不会出现任何问题。

CoCreateInstance(guids,NULL,CLSCTX_INPROC_SERVER,IID_ICA,pcs);

前提CoInitialize(NULL)初始化没出现任何问题。求高人解答。
...全文
934 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
cppzhentan 2011-10-07
  • 打赏
  • 举报
回复
原来是注册COM组件的时候写在注册表中套间项的问题.

谢谢大伙,结贴了.
cppzhentan 2011-10-07
  • 打赏
  • 举报
回复
问题解决了,必须在注册表中添加ThreadingModel=Both,让它支持STA和MTA两个套间.
oyljerry 2011-10-07
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 cppzhentan 的回复:]
其中MyDll是一个LSP的DLL,被其他socket加载是能够CreateInstance实例对象的,而被IE加载,却无法Createinstance,被火狐加载也是一样的,是不是COM宿主方面的原因,谁碰到过呢?谢谢
[/Quote]
如果你的dll只有被IE加载的时候不能创建,而其他自己写的EXE可以,那么可能跟IE Protected Mode有关,看disable以后是否可以.
cppzhentan 2011-10-07
  • 打赏
  • 举报
回复
看来是套间的问题,我详细看看.谢谢提醒.

想请问下有关于实现IMarshal的COM例子吗?
二星马甲 2011-10-07
  • 打赏
  • 举报
回复
不知道你哪里来的信心坚持说COM组件没有问题。
exe能调就能说明COM组件没有问题???


你再仔细看 CoCreateFreeThreadedMarshaler 的msdn说明.

The aggregating object's implementation of IMarshal should delegate QueryInterface calls for IID_IMarshal to the IUnknown of the free-threaded marshaler.

cppzhentan 2011-10-07
  • 打赏
  • 举报
回复
其中MyDll是一个LSP的DLL,被其他socket加载是能够CreateInstance实例对象的,而被IE加载,却无法Createinstance,被火狐加载也是一样的,是不是COM宿主方面的原因,谁碰到过呢?谢谢
cppzhentan 2011-10-07
  • 打赏
  • 举报
回复
COM代码是没问题的,我用exe的测试是能够创建的.就是不知道什么原因在DLL中创建COM对象实例就失败了.
xiaoshang_program 2011-10-07
  • 打赏
  • 举报
回复
不知道你的 AddRef Release 代码写的怎么样?
xiaoshang_program 2011-10-07
  • 打赏
  • 举报
回复
如何这样还有问题 可能就是你的COM组件写的有点问题吧
xiaoshang_program 2011-10-07
  • 打赏
  • 举报
回复
DLLMain 可以不用 CreateInstance

你用loadLibray 那样的加载DLL COM 看看行不行~! ?

我感觉应该可以

cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
在OleView能够查找到IID_ICA的接口,GUID和代码中的一模一样,而且能够查找到CLSID_TEXT的GUID,并且跟代码中的GUID匹配无误。

为什么在DLL中还是出现E_NOINTERFACE的错误呢
cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
CoInitialize(NULL);
IClassFactory* pcf = NULL;

HRESULT hr =CoGetClassObject(CLSID_TEST, CLSCTX_INPROC_SERVER, 0, IID_IClassFactory, (void**)&pcf);
ICA * pcs = NULL;
hr = pcf->CreateInstance(0, IID_ICA, (void**)&pcs);

上面的代码在EXE项目中能够创建出ICA对象,而在DLL项目中为什么创建pcs总为NULL,返回值是E_NOINTERFACE。而EXE项目却是S_OK。

求DLL解决方法。让它能够创建成功。
cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
如果进程内组件同事支持STA和MTA,那么它应该通过CoCreateFreeThreadedMarshaler API的调用.

而这里的00000003-0000-0000-C000-000000000046应该就是CoCreateFreeThreadedMarshaler所创建的.

为什么在调用后CreateInstance还是失败了.
cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
没实现这个IMarshal接口,DLL调用COM接口要实现IMarshal接口吗?
二星马甲 2011-10-06
  • 打赏
  • 举报
回复
00000003-0000-0000-C000-000000000046 是 IMarshal 接口

你COM组件实现的不完整,没有实现IMarshal接口。在需要CoMarshalInterface的情况下失败了...
cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
COM的DLL是自己写的,在MyDll中调用的参数也经过了检查,没问题(跟EXE里面调用的一样顺序)。
cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
其间输出的代码如下:

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
LPOLESTR str;
StringFromIID(riid, &str);
CString strIID;
strIID.Format(_T("%ws.\n"), str);
OutputDebugString(strIID.GetBuffer());
CoTaskMemFree(str);
return AfxDllGetClassObject(rclsid, riid, ppv);
}


还有一个QueryInterface


HRESULT FAR EXPORT CWzdSrv::XWzdClass::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CWzdSrv, WzdClass);
LPOLESTR str;
StringFromIID(iid, &str);
CString strIID;
strIID.Format(_T("%ws.\n"), str);
OutputDebugString(strIID.GetBuffer());
CoTaskMemFree(str);
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}


还真搞不明白为什么iid会变样?难道DLL就不能调用COM的DLL吗?
cppzhentan 2011-10-06
  • 打赏
  • 举报
回复
我尝试写了一个测试的COM DLL,还有一个普通的LSP DLL,其中LSP DLL的代码如下

HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

IClassFactory *pCF=NULL;
hr=::CoGetClassObject(
CLSID_IWzdSrv, // name of dll to load
CLSCTX_INPROC_SERVER,// use dll
NULL, // for DCOM, a COSERVERINFO structure that id's the remote server
// more typically set using OLEView
IID_IClassFactory, // the class factory interface (all COM DLL/EXE's must have this interface)
(LPVOID*)&pCF);

if ( FAILED(hr) )
return ret;

IWzd* iWzd = NULL;

hr = pCF->CreateInstance(
NULL, // aggregated COM object (none)
IID_IWzd, // class to create and object of
(LPVOID*) &iWzd); // returned object pointer

iWzd->Method2(1, 2);

调试了COM DLL,结果输出IID的字符串为:
{00000001-0000-0000-C000-000000000046} ----- IID_IClassFactory
{00000003-0000-0000-C000-000000000046} ----- ?????

不知道为什么CreateInstance跟进的时候,QueryInterface的参数iid居然变成了{00000003-0000-0000-C000-000000000046},而我传递进去的是const IID IID_IWzd =
{0xC177116E,0x9AAA,0x11D3,{0x80,0x5D,0x00,0x00,0x00,0x00,0x00,0x00}};

真让人无语,有人碰到这样的问题吗
二星马甲 2011-10-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cppzhentan 的回复:]
COM的DLL是自己写的,在MyDll中调用的参数也经过了检查,没问题(跟EXE里面调用的一样顺序)。
[/Quote]

自己写的就简单了,单步调试COM工程,看看怎么走到e_nointerface的
用dll所在的exe作为调试程序.
在COM组件工程属性 -- debugging -- command/argument 输入你需要在dll中创建com对象的那个exe
二星马甲 2011-10-05
  • 打赏
  • 举报
回复
2、尝试用DLL导出其它接口,比如Init,在Init内部调用了CoCreateInstance不会死锁,但是发生错误,返回值是E_NOINTERFACE。
----------------

那有可能是COM组件内部初始化的问题。
COM组件是你们自己写的吗?最好问问作者,这个接口对调用环境有啥要求。

比如mfc dll AfxGetStaticModuleState 之类的

猜想:COM作者在写的时候:

do_init
if ( init_failed )
{
return E_NOINTERFACE;
}
加载更多回复(6)
因文件超过20M不能上传,所以拆分为两个文件分次上传 第1章 COM背景知识 1.1 COM的起源 1.1.1 软件业面临的挑战 1.1.2 传统解决方案 1.1.3 面向对象程序设计方法 1.1.4 最终解决方案:组件软件 1.1.5 面向对象的组件模型——COM 1.2 COM的发展历程 1.2.1 COM以前的对象技术:DDE、OLE 1、VBX控件 1.2.2 COM首次亮相:OLE2 1.2.3 Microsoft拥抱Internet:ActiveX 1.2.4 更多的新名词:Windows DNA和COM+ 1.2.5 远程对象:ORBs和DCOM 1.2.6 COM的最新版本:COM+ 1.3 COM技术现状 1.3.1 COM与CORBA 1.3.2 COM与Enterprise Java Beans 1.3.3 Windows之外的COM 小结 第2章 从C++到COM 2.1 C++客户重用C++对象——例程DB 2.1.1 C++对象 2.1.2 客户程序 2.2 将C++对象移进DLL——例程DB_cppdll 2.2.1 成员函数的引出 2.2.2 内存分配 2.2.3 Unicode/ASCII兼容 2.2.4 例程实现 2.2.4.1 修改接口文件 2.2.4.2 修改对象程序 2.2.4.3 修改客户程序 2.3 C++对象使用抽象基类——例程DB_vtbl 2.3.1 问题:私有数据成员被暴露 2.3.2 解决方案:抽象基类 2.3.2.1 什么是抽象基类(Abstract Base Class) 2.3.2.2 实现秘诀:虚函数(Virtual Functions) 2.3.3 使用抽象基类 2.3.4 例程实现 2.3.4.1 修改接口文件 2.3.4.2 修改对象程序 2.3.4.3 修改客户程序 2.4 改由COM库装载C++对象——例程dbalmostcom 2.4.1 COM库 2.4.2 对象创建的标准入口点 2.4.3 标准对象创建API 2.4.4 标准对象注册 2.4.5 例程实现 2.4.5.1 修改接口文件 2.4.5.2 修改对象程序 2.4.5.3 修改客户程序 2.5 将C++对象变成COM对象 2.5.1 引用计数 2.5.2 多接口 2.5.3 IUnknown接口 2.5.4 标准类厂接口:IClassFactory 2.5.5 对象代码的动态卸载 2.5.6 自动注册 2.5.7 例程实现 2.5.7.1 修改接口文件 2.5.7.2 修改对象程序 2.5.7.3 修改客户程序 2.6 为COM对象添加多接口支持 2.6.1 多接口 2.6.2 DEFINE_GUID 2.6.3 例程实现 2.6.3.1 修改接口文件 2.6.3.2 修改对象程序 2.6.3.3 修改客户程序 小结 第3章 COM基础知识 3.1 对象与接口 3.1.1 COM对象 3.1.2 COM接口 3.1.3 IUnknown接口 3.1.3.1 生存期控制:AddRef和Release 3.1.3.2 接口查询:QueryInterface 3.1.4 全球唯一标识符GUID 3.1.5 COM接口定义 3.1.6 接口描述语言IDL 3.2 COM应用模型 3.2.1 客户/服务器模型 3.2.2 进程内组件 3.2.3 进程外组件 3.2.4 COM库 3.2.5 HRESULT返回值 3.2.6 COM与注册表 3.3 COM组件 3.3.1 实现类厂对象 3.3.2 类厂对象的创建 3.3.3 实现自动注册 3.3.4 实现自动卸载 3.4 COM客户 3.4.1 COM对象创建函数 3.4.1.1 CoGetClassObject 3.4.1.2 CoCreateInstance 3.4.1.3 CoCreateInstanceEx 3.4.2 如何调用进程内组件 3.4.3 COM客户调用进程外组件 3.5 进一步认识COM 3.5.1 可重用机制:包容和聚合 3.5.2 进程透明性 3.5.3 安全性机制 小结 第4章 COM扩展技术 4.1 可连接对象机制 4.1.1 客户、接收器与可连接对象 4.1.1.1 接收器 4.1.1.2 可连接对象 4.1.1.3 客户 4.1.2 实现可连接对象 4.1.3 实现接收器 4.1.4 建立接收器与连接点的连接 4.1.5 获得出接口的类型信息 4.2 结构化存储 4.2.1 什么叫结构化存储和复合文件 4.2.2 存储对象和IStorage接口 4.2.2.1 IStorage接口 4.2.2.2 获得IStorage指针 4.2.2.3 释放STATSTG内存 4.2.2.4 枚举存储对象的元

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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