Dll Mingw-w64无法链接版本库

Dll Mingw-w64无法链接版本库,dll,command-line,version,linker-errors,mingw-w64,Dll,Command Line,Version,Linker Errors,Mingw W64,对于使用Mingw-w64构建的开放式windows源代码项目,我认为,如果应用程序意识到它的版本,那就太好了。 为了实现这一点,我复制/粘贴/编辑了一个小包装,它将从应用程序自己的资源中读取版本信息。 当使用VisualStudio环境(使用vcvars32.bat)时,此代码构建良好。 然而,当我尝试用MinGw构建它时,编译器运行得很好,但链接器却不行。出现一个错误,未找到version.dll中的函数: VersSample.cpp:(.text+0x14f):对VerQueryValu

对于使用Mingw-w64构建的开放式windows源代码项目,我认为,如果应用程序意识到它的版本,那就太好了。 为了实现这一点,我复制/粘贴/编辑了一个小包装,它将从应用程序自己的资源中读取版本信息。 当使用VisualStudio环境(使用vcvars32.bat)时,此代码构建良好。 然而,当我尝试用MinGw构建它时,编译器运行得很好,但链接器却不行。出现一个错误,未找到version.dll中的函数:
VersSample.cpp:(.text+0x14f):对VerQueryValue的未定义引用

我确实在build命令行中添加了–lversion编译器开关,但它似乎不起作用。 谁能给我一个提示,我错过了什么

build命令如下所示:

set PATH=C:\Tools\MinGw\mingw64\bin\;%PATH%
windres VersSample.rc -O coff -o VersSample.res
g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ -lversion VersSample.cpp VersSample.res
void AddVersionInfo(WCHAR* pszwOutput, const WCHAR* pszwEntry) {
/** Variables: */
DWORD vLen, langD;
BOOL retVal;
LPVOID retbuf = NULL;
WCHAR fileEntry[256];
/** Fetch-Code: */
HRSRC hVersion = FindResource(NULL, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
if (hVersion != NULL) {
    HGLOBAL hGlobal = LoadResource(NULL, hVersion);
    if (hGlobal != NULL) {
        LPVOID versionInfo = LockResource(hGlobal);
        if (versionInfo != NULL) {
            swprintf(fileEntry, L"\\VarFileInfo\\Translation");
            retVal = VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen);
            if (retVal && vLen == 4) {
                memcpy(&langD, retbuf, 4);
                #ifdef _MSC_VER
                swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%s",
                    (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
                    (langD & 0xff0000) >> 16, pszwEntry);
                #else
                swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%S",
                    (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
                    (langD & 0xff0000) >> 16, pszwEntry);
                #endif
            }else{
                swprintf(fileEntry, L"\\StringFileInfo\\%04X04B0\\%s",
                    GetUserDefaultLangID(), pszwEntry);
            }
            if (VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen)) {
                wcscat(pszwOutput, (WCHAR*)retbuf);
            }
        }
    }
    UnlockResource(hGlobal);
    FreeResource(hGlobal);
}
顺便说一句:我不想根据需要将其放大,但如果有兴趣,我可以发布整个函数。

天哪,我知道了。
我说不出为什么,但这个位置似乎很重要。我把它放在g++调用的末尾,它成功了:

g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ VersSample.cpp VersSample.res -lversion
对于任何感兴趣的人,整个函数如下所示:

set PATH=C:\Tools\MinGw\mingw64\bin\;%PATH%
windres VersSample.rc -O coff -o VersSample.res
g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ -lversion VersSample.cpp VersSample.res
void AddVersionInfo(WCHAR* pszwOutput, const WCHAR* pszwEntry) {
/** Variables: */
DWORD vLen, langD;
BOOL retVal;
LPVOID retbuf = NULL;
WCHAR fileEntry[256];
/** Fetch-Code: */
HRSRC hVersion = FindResource(NULL, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
if (hVersion != NULL) {
    HGLOBAL hGlobal = LoadResource(NULL, hVersion);
    if (hGlobal != NULL) {
        LPVOID versionInfo = LockResource(hGlobal);
        if (versionInfo != NULL) {
            swprintf(fileEntry, L"\\VarFileInfo\\Translation");
            retVal = VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen);
            if (retVal && vLen == 4) {
                memcpy(&langD, retbuf, 4);
                #ifdef _MSC_VER
                swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%s",
                    (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
                    (langD & 0xff0000) >> 16, pszwEntry);
                #else
                swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%S",
                    (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
                    (langD & 0xff0000) >> 16, pszwEntry);
                #endif
            }else{
                swprintf(fileEntry, L"\\StringFileInfo\\%04X04B0\\%s",
                    GetUserDefaultLangID(), pszwEntry);
            }
            if (VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen)) {
                wcscat(pszwOutput, (WCHAR*)retbuf);
            }
        }
    }
    UnlockResource(hGlobal);
    FreeResource(hGlobal);
}
}

请注意,我必须添加一个编译器开关来区分MS VS和MinGw环境,因为它们在sprintf(resp.swprintf)中处理标记的方式似乎不同

这样,如果Resources中有完整的VersionInfo块,则可以访问数据并将其用作:

AddVersionInfo(buffer, L"FileVersion");

…你想要的答案是:有一个像样的解释!非常感谢您提供的详细信息…:-)