为 HtmlHelp API 升级这些 c 样式转换的 c++ 方法是什么?

What is the c++ approach for upgrading these c style casts for HtmlHelp API?

HtmlHelp API 升级这些 c 风格转换的 c++ 方法是什么?

void CMeetingScheduleAssistantApp::DisplayHelpTopic(CString strTopic)
{
    CString strURL = _T("https://help-msa.publictalksoftware.co.uk/") + strTopic;

    if (theApp.UseDownloadedHelpDocumentation())
    {
        // CHM files use 3 letter suffix
        strTopic.Replace(_T(".html"), _T(".htm"));
        HtmlHelp((DWORD_PTR)(LPCTSTR)strTopic, HH_DISPLAY_TOPIC);
    }
    else
        ShellExecute(nullptr, nullptr, strURL, nullptr, nullptr, SW_SHOWDEFAULT);
}

具体来说:

HtmlHelp((DWORD_PTR)(LPCTSTR)strTopic, HH_DISPLAY_TOPIC);


回答评论中的问题:

这很奇怪,因为 x86 的官方文档 HtmlHelpA / HtmlHelpW 确实指出了不同的调用。

它似乎没有在文档中列为 CWinApp class 的一部分。

(LPCTSTR)strTopic 呼叫 CString::operator LPCTSTR()。然后 (DWORD_PTR) 将指针 LPCTSTR 转换为 DWORD_PTR。由于源和目标大小不同,无法从 CString 对象直接转换为 DWORD_PTR。

C++ 类型转换可以与 C 类型转换一样短

HtmlHelp(DWORD_PTR(LPCTSTR(strTopic)), HH_DISPLAY_TOPIC);

MFC CWnd 和 CWinApp 类 具有获取类型 DWORD_PTR

的第一个参数的方法
virtual void HtmlHelp(
    DWORD_PTR dwData,
    UINT nCmd = 0x000F);

reinterpret_cast will always trigger a code analysys warning

在那种情况下,您可以发明自己的指针转换函数。聪明的编译器很可能会优化它:

#include <cstring>

template<class D, class T>
D ptr_cast(T* x) {
    D rv;
    static_assert(sizeof rv == sizeof x);
    std::memcpy(&rv, &x, sizeof rv);
    return rv;
}

然后

HtmlHelp( ptr_cast<DWORD_PTR>(strTopic.GetString()),
          HH_DISPLAY_TOPIC);

在 g++ 和 clang++ 中,显式实例化函数

template DWORD_PTR ptr_cast<DWORD_PTR,char>(char*);

进入汇编代码

unsigned long ptr_cast<unsigned long, char>(char*):
        mov     rax, rdi
        ret

内联和优化后(就像在您的代码中一样),函数调用消失了,只剩下到目标 DWORD_PTRmov(赋值),这正是跟踪reinterpret_cast 会离开。在 MSVC 中,内联它会产生类似的结果:

lea     rdx, OFFSET FLAT:`string'