从 c++ 调用 COM dll,"Class Not Registered"

Calling a COM dll from c++, "Class Not Registered"

本文关键字:Class Not Registered dll c++ 调用 COM      更新时间:2023-10-16

我在Microsoft Visual Basic 2008中创建了一个COM dll。我试图从一个c++项目调用这个dll。在c++中,我使用"#import U:path…MyComDll"。然后,我将以下代码用于DisplayMessage()方法。

FB::variant CmdAccessAPI::filePSV(std::string file)
{
CoInitialize(NULL);
try
{
    _MyComClassPtr spIMyComClass;
    HRESULT hr = spIMyComClass.CreateInstance(__uuidof(_MyComClass));
    if (FAILED(hr)) throw _com_error(hr);
    spIMyComClass->DisplayMessage();
}
    catch (std::exception& e)
{
    CString strMsg(e.what());
    MessageBox(NULL, strMsg, L"Error", MB_OK);
}
catch (_com_error& e)
{
    CString strMsg;
    strMsg = (TCHAR*) e.Description();
    strMsg += _T("n");
    strMsg += (TCHAR*) e.ErrorMessage();
    MessageBox(NULL, strMsg, L"COM Error", MB_OK);
}
CoUninitialize();
return "test";
}

当我调用这个函数时,我得到一个未注册的类错误。我尝试使用regsvr32注册dll,我得到消息"MyComDll.dll已加载,但没有找到DLLREgeisterServer入口点。无法注册此文件。"

我如何注册类并使其工作?

尝试使用admin权限注册它,右键单击命令提示符,选择以管理员身份运行,并为系统提供32个路径。然后使用regsvr32 xyz.dll

如果你不能注册,有两种可能

  1. 您缺少一个依赖库。下载dependency walker,看看缺少了什么。其中一些被标记为缺失的是红鲱鱼(例如ieshims.dll),但其中一个可能是你的

  2. 你的COM设置出了问题。

  3. 你可以调试你的dll,因为它正在注册和挖掘ATL代码,它的失败。

您需要使用regsvr32来注册DLL,正如您所怀疑的。

然而,它给出的错误提示要么是DLL没有包含存根(因此无法注册自己),要么是您试图注册库,而不是存根。

确保你的VS项目和代码设置包括代理/存根函数在你的DLL中,或者确保你注册代理DLL

**include the below code** and export these functions with .def file
wchar_t *convertCharArrayToLPCWSTR(const char* charArray)
{
    wchar_t* wString=new wchar_t[4096];
    MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096);
    return wString;
}
BOOL   Register( HKEY mainKey,const char *subKey,LPCTSTR val_name, DWORD dwType,char * chardata,DWORD dwDataSize)
{
    HKEY hk;
    if (ERROR_SUCCESS != RegCreateKey(mainKey,convertCharArrayToLPCWSTR(subKey),&hk) )
        return FALSE;
    LPCTSTR data=convertCharArrayToLPCWSTR(chardata);
    if (ERROR_SUCCESS != RegSetValueEx(hk,val_name,0,dwType,(CONST BYTE *)data,2*dwDataSize)) 
        return FALSE;
    if (ERROR_SUCCESS != RegCloseKey(hk))   
        return FALSE;
    return TRUE;
}
HRESULT  __stdcall DllRegisterServer(void)
{
    WCHAR *lpwszClsid;
    char szBuff[MAX_PATH]="new multiplication Algorithm";
    char szClsid[MAX_PATH]="", szInproc[MAX_PATH]="",szProgId[MAX_PATH];
    char szDescriptionVal[256]="";
    StringFromCLSID(CLSID_MultiplicationObject,&lpwszClsid);
    sprintf(szClsid,"%S",lpwszClsid);
    sprintf(szInproc,"%s\%s\%s","clsid",szClsid,"InprocServer32");
    sprintf(szProgId,"%s\%s\%s","clsid",szClsid,"ProgId");
    sprintf(szDescriptionVal,"%s\%s","clsid",szClsid);
    Register (HKEY_CLASSES_ROOT,szDescriptionVal,NULL,REG_SZ,szBuff,strlen(szBuff));
    //InprocServer32
    GetModuleFileNameA(g_hModule,szBuff,sizeof(szBuff));
    Register (HKEY_CLASSES_ROOT,szInproc,NULL,REG_SZ,szBuff,strlen((szBuff)));
    //ProgId
    strcpy(szBuff,multiplicationObjProgId);
    Register (HKEY_CLASSES_ROOT,szProgId,NULL,REG_SZ,szBuff,strlen(szBuff));
    return 1;
}
HRESULT  __stdcall DllUnregisterServer(void)
{
    WCHAR *lpwszClsid;
    char szBuff[MAX_PATH]="new multiplication Algorithm";
    char szClsid[MAX_PATH]="", szInproc[MAX_PATH]="",szProgId[MAX_PATH];
    char szDescriptionVal[256]="";
    StringFromCLSID(CLSID_MultiplicationObject,&lpwszClsid);
    sprintf(szClsid,"%S",lpwszClsid);
    sprintf(szInproc,"%s\%s\%s","clsid",szClsid,"InprocServer32");
    sprintf(szProgId,"%s\%s\%s","clsid",szClsid,"ProgId");
    sprintf(szDescriptionVal,"%s\%s","clsid",szClsid);
    RegDeleteKey(HKEY_CLASSES_ROOT,convertCharArrayToLPCWSTR(szInproc));
    RegDeleteKey(HKEY_CLASSES_ROOT,convertCharArrayToLPCWSTR(szProgId));
    RegDeleteKey(HKEY_CLASSES_ROOT,convertCharArrayToLPCWSTR(szDescriptionVal));
    return 1;
}

当供应商体系结构不匹配时,就会发生这种依赖问题。

例如,您可能已经注册了32位的DLL,但您的程序是64位的,反之亦然。

相关文章: