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:
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:
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 or 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:
ADD_DEFINITIONS(-D_UNICODE)
It looks like newer VTK versions do not contain this file any more.
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: https://learn.microsoft.com/en-us/cpp/mfc/mfc-mbcs-dll-add-on
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 add_definitions(-DUNICODE -D_UNICODE).
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.
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.