C#COM对象和CreateDispatch

C#COM对象和CreateDispatch,c#,c++,com,mfc,C#,C++,Com,Mfc,首先:存在使用CreateDispatch的现有代码。出于兼容性/便利性的原因,维护人员不希望更改代码(除了使用新的TLB/GUID) 因此,我必须创建COM对象,该对象使用此限制。最好在C++中(但C++也很好)。 问题是:我完全没有使用COM的经验 这就是我取得的成绩:我在C#中创建了一个COM对象,注册了它,并获得了一个tlb。我检查了注册表,有一个条目:HKEY_CLASSES_ROOT\Wow6432Node\CLSID{36E6BC94-308C-4952-84E6-10904199

首先:存在使用CreateDispatch的现有代码。出于兼容性/便利性的原因,维护人员不希望更改代码(除了使用新的TLB/GUID)

因此,我必须创建COM对象,该对象使用此限制。最好在C++中(但C++也很好)。 问题是:我完全没有使用COM的经验

这就是我取得的成绩:我在C#中创建了一个COM对象,注册了它,并获得了一个tlb。我检查了注册表,有一个条目:HKEY_CLASSES_ROOT\Wow6432Node\CLSID{36E6BC94-308C-4952-84E6-109041990EF7}

看起来不错。下一步:创建一个测试程序(C++)。我创建了一个带有MFC功能的C++控制台项目,导入了TLB。然后,我将以下行添加到main:

CInterface01 server;
COleException* pe = new COleException;
LPTSTR m = new TCHAR[255];

CoInitialize(NULL);

server.CreateDispatch(L"{36E6BC94-308C-4952-84E6-109041990EF7}", pe);
pe->GetErrorMessage(m, 255);
不知何故,CreateDispatch不起作用。在例外情况下,它显示:“类未注册”(什么?!它在注册表中)。更糟糕的是:当我再次运行同一个程序时,它会使Visual Studio崩溃


感觉解决方案就在眼前,但我不知道出了什么问题。

您需要这样的代码:

//interface wrapper method implementations for #import "YouTlbModule.tlb" no_namespace //function CoInitializeEx ( NULL, COINIT_MULTITHREADED); IYouTlbModulePtr ptrYouTlbModule; HRESULT hResult = ptrYouTlbModule.CreateInstance(OLESTR("Your.Component.Name")); //test hResult //Others function call hResult = ptrYouTlbModule.Other(122, L"AAA"); //Call int ret = ptrYouTlbInput.GetErrorMessage(m, 255); //的接口包装器方法实现 #导入“YouTlbModule.tlb”无任何名称空间 //作用 CoInitializeX(空,Conit_多线程); IYouTlbModulePtr ptrYouTlbModule; HRESULT HRESULT=ptrYouTlbModule.CreateInstance(OLESTR(“Your.Component.Name”); //测试hResult //其他函数调用 hResult=ptrYouTlbModule.Other(122,L“AAA”); //召唤 int-ret=ptrYouTlbInput.GetErrorMessage(m,255);
您需要这样的代码:

//interface wrapper method implementations for #import "YouTlbModule.tlb" no_namespace //function CoInitializeEx ( NULL, COINIT_MULTITHREADED); IYouTlbModulePtr ptrYouTlbModule; HRESULT hResult = ptrYouTlbModule.CreateInstance(OLESTR("Your.Component.Name")); //test hResult //Others function call hResult = ptrYouTlbModule.Other(122, L"AAA"); //Call int ret = ptrYouTlbInput.GetErrorMessage(m, 255); //的接口包装器方法实现 #导入“YouTlbModule.tlb”无任何名称空间 //作用 CoInitializeX(空,Conit_多线程); IYouTlbModulePtr ptrYouTlbModule; HRESULT HRESULT=ptrYouTlbModule.CreateInstance(OLESTR(“Your.Component.Name”); //测试hResult //其他函数调用 hResult=ptrYouTlbModule.Other(122,L“AAA”); //召唤 int-ret=ptrYouTlbInput.GetErrorMessage(m,255);
CreateDispatch()有两个重载。如果使用CLSID,则可以使用CLSIDFromString()帮助函数来转换所使用的字符串。另一个接受一个字符串,一个ProgId。您可以使用(比如)“ClassLibrary1.Class1”。
CLSIDFromProgID(L“ComServer2.CSCOMClass01”,&id)
返回一个空类,
CLSIDFromString(L“{36E6BC94-308C-4952-84E6-109041990EF7},&id)
返回
id={CLSID_ComServer2.CSCOMClass01}
,但结果是相同的。如果不知道.NET程序集是如何注册的,您必须用谷歌搜索“未注册的类”。这1.58亿次点击中有一次可以解释您的问题。CreateDispatch()有两个重载。如果使用CLSID,则可以使用CLSIDFromString()帮助函数来转换所使用的字符串。另一个接受一个字符串,一个ProgId。您可以使用(比如)“ClassLibrary1.Class1”。
CLSIDFromProgID(L“ComServer2.CSCOMClass01”,&id)
返回一个空类,
CLSIDFromString(L“{36E6BC94-308C-4952-84E6-109041990EF7},&id)
返回
id={CLSID_ComServer2.CSCOMClass01}
,但结果是相同的。如果不知道.NET程序集是如何注册的,您必须用谷歌搜索“未注册的类”。这1.58亿的点击率说明了你的问题。