能否直接调用COM DLL?

时间:2022-08-29 22:57:39
COM DLL通常有四个Export函数:

DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer

我能否不在系统中注册COM DLL,而是直接在函数中调用上述四个DLL,执行DLL中提供的功能?

31 个解决方案

#1


可是可以,但为什么要这样做呢?你如果不是很了解COM的机制的话最好不要这样做。

#2


应该可以吧,没试过。

#3


肯定不行啦. 直接加载DLL的话, 你只能调用DllGetClassObject, 但是你通过该函数只能得到类工厂的指针.而得到真正的接口指针是CreateInstance,但是
该函数你无法调用. 这个函数是系统在CoCreateInstance中调用的.

#4


//agree  kimryo(轻*轻*前*轻*重)

#5


VCPLUSPLUS6(死鸟) 
有了类工厂难道还不够吗?请明白CreateInstance是类工厂的。

#6


zifzhu, 我没有测试过. 虽然CreateInstance是类工厂的,可是类工厂的头文件是不导出的,所以因无法编译, 而且即使能编译, 有怎么链接呢? 自己的类工厂的CreateInstance()也没有导出,怎么办? 我只是刚入门的, 不正确之处忘赐教.

#7


CoCreateInstance的实现还不是用的ClassFacfory,一般的In-proc COM对象都是ClassFactory new在heap上的.

ATL实现IClassFactory只需要IMPLEMENT_INTERFACE(TClassFactory)就行了,不需要格外的工作。

#8


没有调用的必要啊

#9


如果你愿意用汇编完成那些事, 当然可以!

#10


to 0_0OKll(0_0OKll):
  要用汇编???

#11


可以
前提是你要知道接口
一般通过CoCreateInstance
操作系统会执行CoLoadlibrary,dll导出里面的DllGetClassObject返回类厂的
指针,然后会用这个指针的CreateInstance来创建你要的接口
如下:
typedef HRESULT (STDAPICALLTYPE *pOrnDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);

pOrnDllGetClassObject OrnDllGetClassObject = NULL;
IClassFactory *m_pIClassFactory = NULL;
HMODULE hComDll = CoLoadLibrary(L"DllName");
OrnDllGetClassObject = GetProcAddress(hComDll, "DllGetClassObject");
OrnDllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&m_pIClassFactory);
m_pIClassFactory->CreateInstance(.....);

#12


test

#13


可以
前提是你要知道接口
一般通过CoCreateInstance
操作系统会执行CoLoadlibrary,dll导出里面的DllGetClassObject返回类厂的
指针,然后会用这个指针的CreateInstance来创建你要的接口
如下:
typedef HRESULT (STDAPICALLTYPE *pOrnDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);

pOrnDllGetClassObject OrnDllGetClassObject = NULL;
IClassFactory *m_pIClassFactory = NULL;
HMODULE hComDll = CoLoadLibrary(L"DllName");
OrnDllGetClassObject = GetProcAddress(hComDll, "DllGetClassObject");
OrnDllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&m_pIClassFactory);
m_pIClassFactory->CreateInstance(.....);

#14


如果你直接调用这四个functions,那么你是把这个COM DLL作为一般的Win32 DLL 来使用了;如果作为COM DLL来使用,绝对不能够直接这样调用。因为系统的CCI (CoCreateInstance/Ex)做的工作绝不止简单的直接调用这四个functions,还有包括处理Apartment,创建Proxy/Stub等等诸多问题。COM库为你的COM DLL 提供的很多功能都是通过Hook到CCI上来实现的。


-微软全球技术中心 VC技术支持 

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款 
(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。 
为了为您创建更好的讨论环境,请参加我们的用户满意度调查 
(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。

#15


DLL只暴露这四个引出函数(EXPORTS)!你怎么执行DLL中提供的其它功能???

#16


微软的大哥,当线程模式匹配的话,com dll是不用列集的。还有把你那句话的CCI改成SCM的话会更恰当一些。

#17


如果你真的想用的话,应该是没什么问题。你用dllgetclassobject函数得到IClassFactory接口指针,然后再使用IClassFactory->CreateInstance函数得到你想要得借口,不过前提是你还是必须得知道IClassFactory,及组件里面接口的声明,还不如直接使用CoCreateInstance来得简单。
关于线程的问题,只要dll是线程安全的,就不应该会出现什么问题。不过,就像微软的大哥说的那样,你那样用的话,用的就只是一个按com规范编写的一个dll而已,不是com

#18


本来我的想法和qinzm一样,用代码实现CoGetClassObject的功能,实现方法与qinzm说的一样,可以参考《com本质论》94-95页,里面有详细的解释。不过听了微软大哥一席话,的确CoGetClassObject,CoCreateInstance/Ex除了上述实现的主要功能外,还要做很多初始化工作!

#19


关于汇编, 很是罗嗦:
你去这里看看:

http://ourworld.compuserve.com/homepages/ernies_world/a.htm

#20


ffll,“你那样用的话,用的就只是一个按com规范编写的一个dll而已,不是com”

COM的主要目的之一是松耦合,如果不用SCM就不算COM的话
未免COM的定义也就太肤浅

-------技术不是目的,COM不是耶稣--------

#21


完全仿真CoCreateInstance也可以的
只不过那样比较复杂
没有必要

com不是万能的
也不是那么神秘
任何技术到底都是要调用最基本的api的

#22


好帖子!
诸位大虾都露面了,呵赫!

#23


我正在学习COM,学习!!!!!!!!

#24


多谢各位的指点,我用了qinzm(不归人) 的方法试成功了一个比较简单的基于
COM的DLL,但是请问如何使用类似的方法调用支持IDispatch接口的DLL文件呢?

#25


如果楼主看过《COM 技术内幕》的话,就不会问这个问题了

#26


to waistcoat(马甲):
  我正在看《COM 技术内幕》,但是我不明白你的意思,是说看了这本书以后能很容易解决我的问题还是可以确定我的问题根本无法解决?谢谢。

#27


to chcw():
  此书前几章的例子都是用LoadLibrary函数直接调用的DLL,知道后来引入了CoCreateInstance后,才不再谈直接调用LoadLibrary。
  但是实际上CoCreateInstance的实现,作者也是用了LoadLibrary的,但是COM如何做到位置无关性呢?
  只不过是它先根据组件的CLSID去注册表中查找DLL所在的位置,然后再“私下”里用LoadLibrary调用DLL。

  不过对于启动EXE和远程调用,那是用了LPC和RPC的了,以本次讨论无关。

#28


to waistcoat(马甲):
  多谢大侠指点,小弟看《COM 技术内幕》刚刚开了个头,很多东西还是一直半解,还请兄不吝赐教。

#29


前几章用LoadLibrary只是为了讲解原理。其实少了很多细节的

#30


可以的,

#31


mark

#1


可是可以,但为什么要这样做呢?你如果不是很了解COM的机制的话最好不要这样做。

#2


应该可以吧,没试过。

#3


肯定不行啦. 直接加载DLL的话, 你只能调用DllGetClassObject, 但是你通过该函数只能得到类工厂的指针.而得到真正的接口指针是CreateInstance,但是
该函数你无法调用. 这个函数是系统在CoCreateInstance中调用的.

#4


//agree  kimryo(轻*轻*前*轻*重)

#5


VCPLUSPLUS6(死鸟) 
有了类工厂难道还不够吗?请明白CreateInstance是类工厂的。

#6


zifzhu, 我没有测试过. 虽然CreateInstance是类工厂的,可是类工厂的头文件是不导出的,所以因无法编译, 而且即使能编译, 有怎么链接呢? 自己的类工厂的CreateInstance()也没有导出,怎么办? 我只是刚入门的, 不正确之处忘赐教.

#7


CoCreateInstance的实现还不是用的ClassFacfory,一般的In-proc COM对象都是ClassFactory new在heap上的.

ATL实现IClassFactory只需要IMPLEMENT_INTERFACE(TClassFactory)就行了,不需要格外的工作。

#8


没有调用的必要啊

#9


如果你愿意用汇编完成那些事, 当然可以!

#10


to 0_0OKll(0_0OKll):
  要用汇编???

#11


可以
前提是你要知道接口
一般通过CoCreateInstance
操作系统会执行CoLoadlibrary,dll导出里面的DllGetClassObject返回类厂的
指针,然后会用这个指针的CreateInstance来创建你要的接口
如下:
typedef HRESULT (STDAPICALLTYPE *pOrnDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);

pOrnDllGetClassObject OrnDllGetClassObject = NULL;
IClassFactory *m_pIClassFactory = NULL;
HMODULE hComDll = CoLoadLibrary(L"DllName");
OrnDllGetClassObject = GetProcAddress(hComDll, "DllGetClassObject");
OrnDllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&m_pIClassFactory);
m_pIClassFactory->CreateInstance(.....);

#12


test

#13


可以
前提是你要知道接口
一般通过CoCreateInstance
操作系统会执行CoLoadlibrary,dll导出里面的DllGetClassObject返回类厂的
指针,然后会用这个指针的CreateInstance来创建你要的接口
如下:
typedef HRESULT (STDAPICALLTYPE *pOrnDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);

pOrnDllGetClassObject OrnDllGetClassObject = NULL;
IClassFactory *m_pIClassFactory = NULL;
HMODULE hComDll = CoLoadLibrary(L"DllName");
OrnDllGetClassObject = GetProcAddress(hComDll, "DllGetClassObject");
OrnDllGetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&m_pIClassFactory);
m_pIClassFactory->CreateInstance(.....);

#14


如果你直接调用这四个functions,那么你是把这个COM DLL作为一般的Win32 DLL 来使用了;如果作为COM DLL来使用,绝对不能够直接这样调用。因为系统的CCI (CoCreateInstance/Ex)做的工作绝不止简单的直接调用这四个functions,还有包括处理Apartment,创建Proxy/Stub等等诸多问题。COM库为你的COM DLL 提供的很多功能都是通过Hook到CCI上来实现的。


-微软全球技术中心 VC技术支持 

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款 
(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。 
为了为您创建更好的讨论环境,请参加我们的用户满意度调查 
(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。

#15


DLL只暴露这四个引出函数(EXPORTS)!你怎么执行DLL中提供的其它功能???

#16


微软的大哥,当线程模式匹配的话,com dll是不用列集的。还有把你那句话的CCI改成SCM的话会更恰当一些。

#17


如果你真的想用的话,应该是没什么问题。你用dllgetclassobject函数得到IClassFactory接口指针,然后再使用IClassFactory->CreateInstance函数得到你想要得借口,不过前提是你还是必须得知道IClassFactory,及组件里面接口的声明,还不如直接使用CoCreateInstance来得简单。
关于线程的问题,只要dll是线程安全的,就不应该会出现什么问题。不过,就像微软的大哥说的那样,你那样用的话,用的就只是一个按com规范编写的一个dll而已,不是com

#18


本来我的想法和qinzm一样,用代码实现CoGetClassObject的功能,实现方法与qinzm说的一样,可以参考《com本质论》94-95页,里面有详细的解释。不过听了微软大哥一席话,的确CoGetClassObject,CoCreateInstance/Ex除了上述实现的主要功能外,还要做很多初始化工作!

#19


关于汇编, 很是罗嗦:
你去这里看看:

http://ourworld.compuserve.com/homepages/ernies_world/a.htm

#20


ffll,“你那样用的话,用的就只是一个按com规范编写的一个dll而已,不是com”

COM的主要目的之一是松耦合,如果不用SCM就不算COM的话
未免COM的定义也就太肤浅

-------技术不是目的,COM不是耶稣--------

#21


完全仿真CoCreateInstance也可以的
只不过那样比较复杂
没有必要

com不是万能的
也不是那么神秘
任何技术到底都是要调用最基本的api的

#22


好帖子!
诸位大虾都露面了,呵赫!

#23


我正在学习COM,学习!!!!!!!!

#24


多谢各位的指点,我用了qinzm(不归人) 的方法试成功了一个比较简单的基于
COM的DLL,但是请问如何使用类似的方法调用支持IDispatch接口的DLL文件呢?

#25


如果楼主看过《COM 技术内幕》的话,就不会问这个问题了

#26


to waistcoat(马甲):
  我正在看《COM 技术内幕》,但是我不明白你的意思,是说看了这本书以后能很容易解决我的问题还是可以确定我的问题根本无法解决?谢谢。

#27


to chcw():
  此书前几章的例子都是用LoadLibrary函数直接调用的DLL,知道后来引入了CoCreateInstance后,才不再谈直接调用LoadLibrary。
  但是实际上CoCreateInstance的实现,作者也是用了LoadLibrary的,但是COM如何做到位置无关性呢?
  只不过是它先根据组件的CLSID去注册表中查找DLL所在的位置,然后再“私下”里用LoadLibrary调用DLL。

  不过对于启动EXE和远程调用,那是用了LPC和RPC的了,以本次讨论无关。

#28


to waistcoat(马甲):
  多谢大侠指点,小弟看《COM 技术内幕》刚刚开了个头,很多东西还是一直半解,还请兄不吝赐教。

#29


前几章用LoadLibrary只是为了讲解原理。其实少了很多细节的

#30


可以的,

#31


mark