使用 IShellLink 使我的可执行文件膨胀到 20KB

Using IShellLink bloats my executable to 20KB

很长一段时间以来,我都在使用函数在 Windows 中创建链接。来源是纯 C:

void CreateLink(TCHAR *PathObj, TCHAR *PathLink, TCHAR *ArgV)
{
    IShellLink *psl;
    IPersistFile *ppf;

    if (SUCCEEDED(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void**)&psl))) {
        psl->lpVtbl->SetPath(psl, PathObj);
        psl->lpVtbl->SetArguments(psl, ArgV);
        if (SUCCEEDED(psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (void**)&ppf))) {
            ppf->lpVtbl->Save(ppf, PathLink, TRUE);
            ppf->lpVtbl->Release(ppf);
        }
        psl->lpVtbl->Release(psl);
    }
}

此功能完美运行,但我注意到使用 MinGW 4.7.4,仅由于此功能,我的可执行文件大了大约 10KB。 我现在已经把MinGW更新到5.3.0版本了,现在这个功能增加了可执行文件的大小大约20KB。 代码针对大小 (-Os) 进行了优化,并删除了符号。事实上,这个膨胀是链接器在解析 "IID_IShellLink".

时造成的

所以,我的问题是:有没有办法避免这种膨胀?

终于,我找到了解决这个问题的方法。我们只需要直接在函数中定义 GUID。有了它,链接器不再要求 uuid 库,可执行文件尽可能小,并且运行完美。
两个 GUID 都可以在 objidl.h (MinGW 6.2.0) 中找到。

void CreateLink(TCHAR *PathObj, TCHAR *PathLink, TCHAR *ArgV)
{
    GUID IID_IShellLinkW = {0x000214f9, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
    GUID IID_IPersistFile = {0x0000010b, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
    IShellLink *psl;
    IPersistFile *ppf;

    if (SUCCEEDED(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (void**)&psl))) {
        psl->lpVtbl->SetPath(psl, PathObj);
        psl->lpVtbl->SetArguments(psl, ArgV);
        if (SUCCEEDED(psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (void**)&ppf))) {
            ppf->lpVtbl->Save(ppf, PathLink, TRUE);
            ppf->lpVtbl->Release(ppf);
        }
        psl->lpVtbl->Release(psl);
    }
}

这并没有解释链接器包含的数据的含义,但至少这回答了问题。