Проект VS COM компилируется в 32-битном, но выдает ошибку C2259 при попытке скомпилировать 64-битный

Здравствуйте, в настоящее время я использую Visual Studio 2010, и у меня есть расширение оболочки контекстного меню, полностью работающее в 32-битной версии на 32-битной машине, поэтому все методы существуют. Это проект ATL. Никаких ошибок или даже предупреждений на 32 бит.

Вот в чем проблема. Когда я захожу в диспетчер конфигурации в Visual Studio и переключаю платформу активного решения с Win32 на x64 и пытаюсь скомпилировать, я получаю сообщение об ошибке «Ошибка C2259 :'ATL ::CCOMObject :не может создать экземпляр абстрактного класса».

Поскольку этот же самый проект компилируется и работает в 32-битной версии, почему он выдает мне эту ошибку для x64?

Любые идеи или точка в правильном направлении будут оценены.
Основные методы, которые необходимы и реализуются следующим образом:

STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT);
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);

Чтобы сэкономить пространство кода, создайте проект Atl. После создания исходных элементов добавьте новый класс «TestingContextMenu». Остальная часть кода будет ссылаться на него.

stdafk.h

#include "resource.h"
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <shlobj.h>
#include <comdef.h>

#include <string>
#include <list>
typedef std::list< std::basic_string<TCHAR> > string_list;

TestingContextMenu.h Будут включены только те части, которые были добавлены/изменены

#include "stdafx.h"
using namespace std;
class ATL_NO_VTABLE CTestingContextMenu:
        public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CTestingContextMenu, &CLSID_TestingContextMenu>,
    public IShellExtInit,
    public IContextMenu
    {
        // Comment out or remove IDispatch
BEGIN_COM_MAP(CMainMagnimbusContextMenu)
    //COM_INTERFACE_ENTRY(ITestingContextMenu)
    //COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IShellExtInit)
    COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()

protected:
    TCHAR m_szFile[MAX_PATH];
    list<string> Filenames;
    list<string> FilenamesCopier;
public:
    STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);

    STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT);
    STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
    STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
};  //There is other code within this but it is autogenerated

TestingContextMenu.cpp

#include "stdafx.h"
#include "TestingContextMenu"
#include <sstream>
using namespace std;
#pragma comment(lib, "comsuppw")

STDMETHODIMP CMainMagnimbusContextMenu::Initialize ( 
  LPCITEMIDLIST pidlFolder,
  LPDATAOBJECT pDataObj,
  HKEY hProgID )
  {
  FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stg = { TYMED_HGLOBAL };
    HDROP     hDrop;

    if ( FAILED( pDataObj->GetData ( &fmt, &stg ) ))
        return E_INVALIDARG;
    hDrop = (HDROP) GlobalLock ( stg.hGlobal );

    UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
   HRESULT hr = S_OK;

   if ( 0 == uNumFiles )
    {
       GlobalUnlock ( stg.hGlobal );
       ReleaseStgMedium ( &stg );
       return E_INVALIDARG;
    }

   UINT counter = 0;
    // Get the name of the every file and store it in our member variable m_szFile.
   for(counter = 0; counter < uNumFiles; counter++)
   {
        if ( 0 == DragQueryFile ( hDrop, counter, m_szFile, MAX_PATH ) )
        {   
            hr = E_INVALIDARG;
        }
        wchar_t* t = _wcsdup(m_szFile);
        char ch[260];
        char DefChar = ' ';
        WideCharToMultiByte(CP_ACP,0,t,-1, ch,260,&DefChar, NULL);
        string ss(ch);
        Filenames.push_back(ss);
        FilenamesCopier.push_back(ss);
   }

   GlobalUnlock ( stg.hGlobal );
   ReleaseStgMedium ( &stg );

   return hr;
}

Остальные функции доступны по запросу. Однако я заметил кое-что новое. Если у вас реализована только вышеуказанная функция и код, а диспетчер конфигурации настроен на сборку x64, вы получите исходную ошибку, с которой я сталкиваюсь. Это даже означает отказ от реализации QueryContextMenu, GetCommandString или команды вызова. Единственная ошибка, которую вы получите с этой настройкой, - это мой оригинал, чего мы и ожидали, поскольку они не реализованы. Однако переключите этот диспетчер конфигурации обратно в Win32, и вы получите ожидаемые ошибки, такие как 3 неразрешенных внешних и 3 ошибки, следующие за ним с именами GetCommandString, InvokeCommand и QueryContextMenu. Опять же ожидается, если они не реализованы, но почему компилятор на x64 распознает только мою первоначальную ошибку, что многие люди предположили бы, а не реализованные методы, но в наборе win32 он показывает полные ошибки, когда они не реализованы.

Предыдущий абзац был просто тем, что я заметил. У меня все 3 метода реализованы правильно и правильно компилируются в Win32, но не в x64.

5
задан Rob 1 August 2012 в 23:22
поделиться