Fix 'ICU.dll is not available' on Windows 10 1809
The combined icu.dll was only made part of the OS in Windows 10 1903. Since we still support 1809, we cannot rely on it. The old API unfortunately also requires explicit initialization / deinitialization of COM with CoInitializeEx / CoUninitialize. Make sure that initialization happens in the current thread by calling the qt_win_ensureComInitializedOnThisThread() helper function in relevant code paths. Fixes: QTBUG-134540 Pick-to: 6.9 6.9.0 Change-Id: I01677ccc8bfd3780267e3c788295d4ac2b0ed93c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
f5ac4a7f14
commit
fde0022854
@ -876,9 +876,10 @@ qt_internal_extend_target(Core CONDITION WIN32
|
|||||||
text/qlocale_win.cpp
|
text/qlocale_win.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Switch this to just 'icu' once we can expect Windows 10 version 1903
|
||||||
qt_internal_extend_target(Core CONDITION QT_FEATURE_winsdkicu
|
qt_internal_extend_target(Core CONDITION QT_FEATURE_winsdkicu
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
icu
|
icuuc icuin
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_internal_extend_target(Core CONDITION WASM
|
qt_internal_extend_target(Core CONDITION WASM
|
||||||
|
@ -15,14 +15,21 @@
|
|||||||
#include <QtCore/qbytearraylist.h>
|
#include <QtCore/qbytearraylist.h>
|
||||||
|
|
||||||
#if QT_CONFIG(icu)
|
#if QT_CONFIG(icu)
|
||||||
|
|
||||||
#include <unicode/ucnv.h>
|
#include <unicode/ucnv.h>
|
||||||
#include <unicode/ucnv_cb.h>
|
#include <unicode/ucnv_cb.h>
|
||||||
#include <unicode/ucnv_err.h>
|
#include <unicode/ucnv_err.h>
|
||||||
#include <unicode/ustring.h>
|
#include <unicode/ustring.h>
|
||||||
#define QT_USE_ICU_CODECS
|
#define QT_USE_ICU_CODECS
|
||||||
|
#define QT_COM_THREAD_INIT
|
||||||
|
|
||||||
#elif QT_CONFIG(winsdkicu)
|
#elif QT_CONFIG(winsdkicu)
|
||||||
|
|
||||||
#include <icu.h>
|
#include <icu.h>
|
||||||
|
#include <private/qfunctions_win_p.h>
|
||||||
#define QT_USE_ICU_CODECS
|
#define QT_USE_ICU_CODECS
|
||||||
|
#define QT_COM_THREAD_INIT qt_win_ensureComInitializedOnThisThread();
|
||||||
|
|
||||||
#endif // QT_CONFIG(icu) || QT_CONFIG(winsdkicu)
|
#endif // QT_CONFIG(icu) || QT_CONFIG(winsdkicu)
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@ -1841,6 +1848,7 @@ void QStringConverter::State::reset() noexcept
|
|||||||
{
|
{
|
||||||
if (flags & Flag::UsesIcu) {
|
if (flags & Flag::UsesIcu) {
|
||||||
#if defined(QT_USE_ICU_CODECS)
|
#if defined(QT_USE_ICU_CODECS)
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
UConverter *converter = static_cast<UConverter *>(d[0]);
|
UConverter *converter = static_cast<UConverter *>(d[0]);
|
||||||
if (converter)
|
if (converter)
|
||||||
ucnv_reset(converter);
|
ucnv_reset(converter);
|
||||||
@ -2162,6 +2170,7 @@ struct QStringConverterICU : QStringConverter
|
|||||||
{
|
{
|
||||||
static void clear_function(QStringConverter::State *state) noexcept
|
static void clear_function(QStringConverter::State *state) noexcept
|
||||||
{
|
{
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
ucnv_close(static_cast<UConverter *>(state->d[0]));
|
ucnv_close(static_cast<UConverter *>(state->d[0]));
|
||||||
state->d[0] = nullptr;
|
state->d[0] = nullptr;
|
||||||
}
|
}
|
||||||
@ -2176,6 +2185,7 @@ struct QStringConverterICU : QStringConverter
|
|||||||
|
|
||||||
static QChar *toUtf16(QChar *out, QByteArrayView in, QStringConverter::State *state)
|
static QChar *toUtf16(QChar *out, QByteArrayView in, QStringConverter::State *state)
|
||||||
{
|
{
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
ensureConverter(state);
|
ensureConverter(state);
|
||||||
|
|
||||||
auto icu_conv = static_cast<UConverter *>(state->d[0]);
|
auto icu_conv = static_cast<UConverter *>(state->d[0]);
|
||||||
@ -2212,6 +2222,7 @@ struct QStringConverterICU : QStringConverter
|
|||||||
|
|
||||||
static char *fromUtf16(char *out, QStringView in, QStringConverter::State *state)
|
static char *fromUtf16(char *out, QStringView in, QStringConverter::State *state)
|
||||||
{
|
{
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
ensureConverter(state);
|
ensureConverter(state);
|
||||||
auto icu_conv = static_cast<UConverter *>(state->d[0]);
|
auto icu_conv = static_cast<UConverter *>(state->d[0]);
|
||||||
UErrorCode err = U_ZERO_ERROR;
|
UErrorCode err = U_ZERO_ERROR;
|
||||||
@ -2277,6 +2288,7 @@ struct QStringConverterICU : QStringConverter
|
|||||||
{
|
{
|
||||||
Q_ASSERT(name);
|
Q_ASSERT(name);
|
||||||
Q_ASSERT(state);
|
Q_ASSERT(state);
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
UConverter *conv = ucnv_open(name, &status);
|
UConverter *conv = ucnv_open(name, &status);
|
||||||
if (status != U_ZERO_ERROR && status != U_AMBIGUOUS_ALIAS_WARNING) {
|
if (status != U_ZERO_ERROR && status != U_AMBIGUOUS_ALIAS_WARNING) {
|
||||||
@ -2383,6 +2395,7 @@ struct QStringConverterICU : QStringConverter
|
|||||||
QStringConverter::State *state,
|
QStringConverter::State *state,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
UConverter *conv = createConverterForName(name, state);
|
UConverter *conv = createConverterForName(name, state);
|
||||||
if (!conv)
|
if (!conv)
|
||||||
@ -2617,6 +2630,7 @@ static qsizetype availableCodecCount()
|
|||||||
#if !defined(QT_USE_ICU_CODECS)
|
#if !defined(QT_USE_ICU_CODECS)
|
||||||
return QStringConverter::Encoding::LastEncoding;
|
return QStringConverter::Encoding::LastEncoding;
|
||||||
#else
|
#else
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
/* icu contains also the names of what Qt provides
|
/* icu contains also the names of what Qt provides
|
||||||
except for the special Locale one (so add one for it)
|
except for the special Locale one (so add one for it)
|
||||||
*/
|
*/
|
||||||
@ -2647,6 +2661,7 @@ QStringList QStringConverter::availableCodecs()
|
|||||||
if (index == 0) // "Locale", not provided by icu
|
if (index == 0) // "Locale", not provided by icu
|
||||||
return QString::fromLatin1(
|
return QString::fromLatin1(
|
||||||
encodingInterfaces[QStringConverter::Encoding::System].name);
|
encodingInterfaces[QStringConverter::Encoding::System].name);
|
||||||
|
QT_COM_THREAD_INIT
|
||||||
// this mirrors the setup we do to set a converters name
|
// this mirrors the setup we do to set a converters name
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
auto icuName = ucnv_getAvailableName(int32_t(index - 1));
|
auto icuName = ucnv_getAvailableName(int32_t(index - 1));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user