We are in the process of upgrading to VTK v9.2.6. We have a Windows MFC program and it gives debug asserts in AfxGetInstanceHandle(), apparently because the VTK vtkGUISupportMFCd.dll appears to be linked to mfc140d.dll, not mfc140ud.dll like the rest of our code. How to force it to link against the Unicode version of MFC? Adding -DUNICODE to CXXFLAGS did not help. This is our current build of vtk, in a Windows bash shell script:
export CMAKE_GENERATOR='Visual Studio 16 2019'
export CXXFLAGS="-DUNICODE -D_UNICODE -Od -MP"
cmake -A x64 -Wno-dev \
-S $DOWNLOAD_ROOT/$PROJECT \
-B $BUILD_ROOT/$PROJECT \
-D CMAKE_INSTALL_PREFIX=$INSTALL_ROOT/$PROJECT \
-D CMAKE_CONFIGURATION_TYPES=Debug \
-D VTK_MODULE_ENABLE_VTK_GUISupportMFC=YES \
-D VTK_RELOCATABLE_INSTALL=ON \
-D VTK_VERSIONED_INSTALL=OFF \
Might be a cmake issue. Instead of changing the CXXFLAGS globally, you can try setting the flags by editing
GUISupport/MFC/CmakeLists.txt around line 60:
_AFXDLL _UNICODE UNICODE)
But really I’m not sure what magic is required for CMake to tell Visual Studio to link to the right MFC library. Maybe an MFC/CMake expert is reading this and can chime in.
Thanks, hacking the CMakeLists.txt indeed got this thing working!
This page https://gitlab.kitware.com/vtk/vtk/-/issues/18115 suggests VTK is now using UTF-8 internally and has thus removed UNICODE everywhere. Our own code also uses UTF-8 internally, so that would be fine, but the thing is that I also need to link against a pile of legacy MFC-based libraries which have no idea about UTF-8 and require to be built with UNICODE in order to cope.
Suspecting that the GUISupport/MFC/CmakeLists.txt should still define UNICODE, maybe in a configurable way.
But as far as I understand, it never did define UNICODE, and the CXXFLAGS has always been the only way for people to do a UNICODE build of VTK (unless they manually edit the CMakeLists.txt).
So I’m a bit confused about why this MFC unicode issue would appear for VTK 9.2, but not for older versions of VTK.
My guess is that the library to link is specified using
#pragma comment(lib, "…") (“autolinking”) based on the preprocessor state. I don’t see where VTK ever defined
UNICODE itself either.
I know we removed usage of it, but I’ve not found where VTK defined
-DUNICODE or the like; it seems like it was always a user-selection thing via
CMAKE_CXX_FLAGS or something.
I found where UNICODE was defined in VTK 7.1.0 : in GUISupport/MFC/VTKMFCSettings.cmake , included by GUISupport/MFC/CMakeLists.txt :
# Newer versions of MSVC do not support non-Unicode MFC, which is a good.
# However, we need to convince also CMake about that:
It looks like newer VTK versions do not contain this file any more.
I’m not seeing that in VTK’s history…
Anyways, if we need it for modern MFC, let’s get the MFC module to do what is necessary.
I think that the comment about MSVC not supporting non-Unicode MFC is out-of-date. After some digging, I found that this may have been the case for Visual Studio 2013 and 2015, but not for Visual Studio 2017 and later:
The current MSVC documentation makes it very clear that both Unicode and non-Unicode versions of the library are supported:
There is also documentation on the use of
_UNICODE with MFC:
So it seems that
_UNICODE in MFC needs to be configurable, and possibly
_MBCS as well.
Edit: another useful link, showing the options that are available in the Visual Studio GUI itself:
Given that VTK is UTF-8 everywhere now (much thanks to @toddy), do we want the Unicode version? IIUC, UTF-8 uses the
A functions, but Unicode would be the
W variants. I’m…not sure what that means for MFC.
In general, we would want the Unicode version, for the same reason that the KWSys CMakeLists.txt uses
When VTK made the utf-8 switchover, it switched to using KWSys to open the files, and VTK uses KWSys to perform the conversion from wide characters to utf-8 and back again. So VTK does its IO via the ‘W’ functions in KWSys, not via the ‘A’ functions.
The wrapping tools, which don’t use KWSys, explicitly use the ‘W’ functions for all I/O, and call
MultiByteToWideChar(CP_UTF8, ... directly.
The traditional way to use Unicode with MFC has been to use UNICODE and W functions. Given that most MFC projects are probably legacy and nobody wants to port them to use UTF-8 instead (which was not even possible in recent past, not sure about current state), I believe VTK should support the MFC UNICODE version, probably in a configurable way.
I now found out from svn history that the UNICODE define was added by our own team, so indeed it was not in official VTK. Sorry for the noise!
Actually UTF-8 uses the W variants via KWSYS conversion.
The only places where I used the A variants for the Windows API was for hard-coded ANSI text in the source code or class names, which I assumed would always be plain English.