如何让CoCreateInstance创建一个新对象
我编写了一个 exe(C++,MFC),它公开了一个用于创建 COM 对象的接口,即我的“com 服务器”。 COM 对象具有显示对话框的功能。我现在编写了第二个 exe 来创建这个 COM 对象并运行该函数,即我的“com 客户端”。
这是“com 客户端”中的代码:
MKS::IApplication* pMKSApp = nullptr; // the com object
CLSID id;
HRESULT hr0 = CoInitialize(NULL);
HRESULT hr1 = CLSIDFromProgID(OLESTR("MKS.Application"), &id);
HRESULT hr2 = CoCreateInstance(id, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pMKSApp));
pMKSApp->ShowDialog(); // the function which displays the dialog
// at this point there is only one "com server" exe running
pMKSApp->Release();
当我运行客户端时,功能运行良好 - 对话框显示并且运行良好。但是,如果我运行“com 服务器”exe,然后运行“com 客户端”exe(两者同时运行),则会显示该对话框,但“com 服务器”变为非活动状态 - 该对话框显示为服务器作为其父级。如果我检查任务管理器,就会发现只有一个“com 服务器”实例正在运行。看起来 CoCreateInstance 并不是创建一个新的服务器,而是重用已经运行的服务器。
如何让“com客户端”创建“com服务器”的新实例? (我是 com 新手,所以如果我的术语不正确,我深表歉意。)
I have written an exe (C++, MFC) that exposes an interface for creating a COM object, i.e., my "com server". The COM object has a function that displays a dialog. I now wrote a second exe that creates this COM object and runs the function, i.e., my "com client".
Here is the code in the "com client":
MKS::IApplication* pMKSApp = nullptr; // the com object
CLSID id;
HRESULT hr0 = CoInitialize(NULL);
HRESULT hr1 = CLSIDFromProgID(OLESTR("MKS.Application"), &id);
HRESULT hr2 = CoCreateInstance(id, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pMKSApp));
pMKSApp->ShowDialog(); // the function which displays the dialog
// at this point there is only one "com server" exe running
pMKSApp->Release();
When I run the client the functionality works fine - the dialog is displayed and works well. However, if I am running the "com server" exe and then run the "com client" exe (both running at the same time), the dialog is displayed but the "com server" becomes inactive - the dialog is being displayed with the server as its parent. If I check task manager, there is only one instance of the "com server" running. It seems that CoCreateInstance is not creating a new server but reusing the one that is already running.
How, can I get the "com client" to create a new instance of the "com server"? (I am new to com so I apologize if my terminology is incorrect.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
西蒙,谢谢你的指导。正如您所说,问题是“服务器问题”而不是“客户端问题”。而且,当我深入研究代码时,我发现这更多是 MFC 问题。
在我的代码中,我使用 MFC 的 IMPLMENT_OLECREATE_FLAGS 宏来实例化一个 COleObjectFactory 对象,该对象负责创建类工厂。查看 COleObjectFactory (olefact.cpp) 的 MFC 源代码,调用 CoRegisterClassObject 函数:
m_bMultiInstance 变量的值决定使用哪个 REGCLS 值。不幸的是,该值是在 IMPLMENT_OLECREATE_FLAGS 宏中设置的。以下是宏定义:
构造的第三个参数为 FALSE - 这是 m_bMultiInstance 变量的值。因此,我想出的解决方案是重新定义宏,并将第三个参数设置为 TRUE。
现在看来它正在按预期工作。在任务管理器中,我现在可以看到当客户端发出请求时,会创建服务器应用程序的新实例。再次感谢您的帮助。
Simon, thank you for the guidance. As you said, the issue was a "server issue" rather than a "client issue". And, as I dug into the code, I found it was more of a MFC issue.
Within my code, I use MFC's IMPLEMENT_OLECREATE_FLAGS macro which instantiates a COleObjectFactory object which takes care of creating the class factory. Looking at the MFC source code for COleObjectFactory (olefact.cpp) the CoRegisterClassObject function is called:
The value of the m_bMultiInstance variable decides which REGCLS value to use. Unfortunately, this value is set from within the IMPLEMENT_OLECREATE_FLAGS macro. Here is the macro definition:
The third argument to the construction is FALSE - this is the value of the m_bMultiInstance variable. So, the solution I came up with was to redefine the macro with the third argument set to TRUE.
It now seems to be working as desired. In task manager I can now see that a new instance of the server application is created when a request is made by the client. Thanks again for the help.