VS COM项目以32位编译,但在尝试编译64位时引发错误C2259
VS COM Project Compiles in 32bit but throws error C2259 when trying to compile 64bit
你好,我目前正在运行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
测试上下文菜单.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或invoke命令。这个设置的唯一错误是我的原始设置,这是我们所期望的,因为它们没有实现。但是,将配置管理器切换回Win32,您会得到预期的错误,例如3个未解析的外部错误,以及随后命名GetCommandString、InvokeCommand和QueryContextMenu的3个错误。如果它们没有实现,这也是意料之中的事,但为什么x64上的编译器只识别我的原始错误,这是很多人认为的,不是实现的方法,但在win32集上,它显示了未实现时的全部错误。
前一段只是我注意到的。我确实正确地实现了所有3个方法,并在Win32中正确编译,但不是x64。
您的GetCommandString
参数与接口方法定义的参数不匹配。
您的
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT)
需要
STDMETHODIMP GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT)
在Win32
中,不匹配并不那么重要(参数类型解析为同一类型),而在x64
中则变得重要。编译器生成输出应该对此给出提示,包括缺少的方法名。
- G++无法编译Win7,64位(MinGW.org GCC-6.3.0-1)
- 在 Slackware 14.2 64 位上使用 ACE 库编译错误
- 在 64 位 Linux armv8 计算机上编译 32 位二进制文件时遇到问题
- 如何将 32 位编译二进制转换为 64 位
- 将32位和64位应用程序(具有相同代码)编译为一个EXE
- 在 64 位 Windows 上运行的 32 位应用程序是否仍然需要使用 SAFESEH 进行编译
- 在Java(JNI)中与Mingw C 一起编译64位静态LIB
- 在 MSVC 2010 中编译 64 位应用程序
- 在visualstudio2010下编译64位
- 我想在Windows上使用Clang从C++编译64位代码-找不到stdio.h文件
- VS COM项目以32位编译,但在尝试编译64位时引发错误C2259
- 如何使用代码块编译64位SDL代码(没有管理权限)
- Xcode:使用 32 位库编译 64 位应用程序
- 尝试使用 g++ 编译 64 位窗口的.cpp
- 如何使用G++w/CodeBlocks编译64位
- 如何使用visual c++2008编译64位
- 无法编译 64 位 Visual Studio 2010 项目
- 为windows和mac编译64位架构的OpenAES
- 抱歉,未实现:未在中编译64位模式
- 编译 64 位时处理由于 C++ C2664 导致的向下转换的最佳做法