我正在尝试与OEM库进行交互。一切都在一台计算机上运行,但我在另一台计算机上遇到了很多问题。
我的代码抛出了COM异常,但我无法弄清楚没有ErrorMessage();
的错误代码的含义
代码
#include "stdafx.h"
#include <afx.h>
#include <iostream>
using namespace std;
#import "MTBApi.tlb" named_guids //raw_interfaces_only
using namespace MTBApi;
void DisplayError(_com_error* e)
{
CString message;
// if it is an application error thrown by .NET
if (e->Error() >= 0x80041000)
{
IErrorInfo* info;
BSTR msg;
info = e->ErrorInfo();
info->GetDescription(&msg);
info->Release();
message = CString(msg);
}
// other com errors
else
{
message = e->ErrorMessage();
}
cout << "MTB Error: " << message <<":"<<(unsigned int) e->Error()<< endl;
}
int main(int argc, char **argv)
{
for (int i = 0 ; i < 4 ; i++)
{
IMTBConnectionPtr m_MTBConnection;
try
{
cout <<"1" << endl;
HRESULT a = CoInitializeEx(NULL,COINIT_SPEED_OVER_MEMORY);
cout <<"2" << endl;
m_MTBConnection = IMTBConnectionPtr(CLSID_MTBConnection);
cout <<"3" << endl;
m_MTBConnection->Close();
cout <<"4" << endl;
CoUninitialize();
cout <<"5" << endl;
}
catch(_com_error e)
{
DisplayError(&e);
}
cout << endl;
}
}
运行时输出
1
2
MTB Error: 00000000002205F8:2147746132
1
2
MTB Error: 00000000002205F8:2147746132
1
2
MTB Error: 00000000002205F8:2147746132
1
2
MTB Error: 00000000002205F8:2147746132
来自Dependency Walker的相当详细的输出
答案 0 :(得分:2)
cout << "MTB Error: " << message <<":"<<(unsigned int) e->Error()<< endl;
cout
不是很擅长显示Unicode字符串,它只显示字符串指针值。当然没用,请改用wcout
。并支持以十六进制显示错误代码。 0x80040154是一个非常常见的COM错误,“未注册类”。关于它的成千上万的问题,你只需要正确注册COM服务器。如果您不知道如何做,请询问供应商或作者。
答案 1 :(得分:1)
00000000002205F8
看起来像一个内存指针。您正在将CString
传递给cout
,其仅接受char*
或std::string
字符串值。也许CString
包含一个未正确转换为Ansi的Unicode字符串。此外,在调用IErrorInfo::GetDescription()
时,您正在泄露返回的BSTR
。完成使用后,您需要使用SysFreeString()
释放它。
错误代码2147746132
(十六进制0x80040154
)是Severity = FAIL,Facility = FACILITY_ITF,Code = 340。 FACILITY_ITF通常表示错误代码是由失败的接口定义的自定义错误代码。但在这种情况下,0x80040154
也是标准错误代码:REGDB_E_CLASSNOTREG
。
答案 2 :(得分:1)
如果您的问题是纠正您正在获得的错误 然后问题就像@Remy指出的那样,你的com程序集没有在你正在执行你的程序的机器中注册,而不是在它注册的另一台机器上注册。通过在命令提示符下运行以下命令来注册程序集(例如,对于例如C:\驱动器中的COMAssembly.dll)。
regsvr32 c:\COMAssembly.dll
如果它是一个C ++ com程序集,如果它的C#程序集使用命令
注册它 regasm c:\COMAssembly.dll
(其中regasm可以在VS命令提示符下运行,否则如果你在正常的命令提示符下运行,那么你必须先调用vsvars32.bat然后调用regasm)