gpt4 book ai didi

c++ - VS COM 项目在 32 位编译但在尝试编译 64 位时抛出错误 C2259

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:25:53 25 4
gpt4 key购买 nike

您好,我目前正在运行 Visual Studio 2010,并且有一个上下文菜单 shell 扩展在 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 个 Unresolved external 错误,以及 3 个错误,其后命名为 GetCommandString、InvokeCommand 和 QueryContextMenu。再次期望它们是否未实现,但为什么 x64 上的编译器只识别我的原始错误,这是很多人认为的错误,而不是已实现的方法,但在 win32 集上,它在未实现时显示完整错误。

上一段只是我注意到的。我确实在 Win32 中正确实现了所有 3 种方法并正确编译,但在 x64 中却没有。

最佳答案

您的 GetCommandString 参数与接口(interface)方法定义的参数不匹配。

你的

STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT)

需要

STDMETHODIMP GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT)

Win32 中,不匹配不是那么重要(参数类型解析为同一类型),而在 x64 中变得很重要。编译器构建输出应该已经为您提供了提示,包括缺少的方法名称。

关于c++ - VS COM 项目在 32 位编译但在尝试编译 64 位时抛出错误 C2259,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11768016/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com