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)初始化没出现任何问题。求高人解答。
...全文
933 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)

3,245

社区成员

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

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