?? qlibrary.cpp
字號:
if (lib) lib->errorString = file.errorString(); if (qt_debug_component()) { qWarning("%s: %s", (const char*) QFile::encodeName(library), qPrintable(qt_error_string(errno))); } return false; } QByteArray data; char *filedata = 0; ulong fdlen = 0;#ifdef USE_MMAP char *mapaddr = 0; size_t maplen = file.size(); mapaddr = (char *) mmap(mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0); if (mapaddr != MAP_FAILED) { // mmap succeeded filedata = mapaddr; fdlen = maplen; } else { // mmap failed if (qt_debug_component()) { qWarning("mmap: %s", qPrintable(qt_error_string(errno))); } if (lib) lib->errorString = QLibrary::tr("Could not mmap '%1': %2") .arg(library) .arg(qt_error_string());#endif // USE_MMAP // try reading the data into memory instead data = file.readAll(); filedata = data.data(); fdlen = data.size();#ifdef USE_MMAP }#endif // USE_MMAP // verify that the pattern is present in the plugin const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA"; const ulong plen = qstrlen(pattern); long pos = qt_find_pattern(filedata, fdlen, pattern, plen); bool ret = false; if (pos >= 0) ret = qt_parse_pattern(filedata + pos, version, debug, key); if (!ret && lib) lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library);#ifdef USE_MMAP if (mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0) { if (qt_debug_component()) qWarning("munmap: %s", qPrintable(qt_error_string(errno))); if (lib) lib->errorString = QLibrary::tr("Could not unmap '%1': %2") .arg(library) .arg( qt_error_string() ); }#endif // USE_MMAP file.close(); return ret;}#endif // Q_OS_UNIXtypedef QMap<QString, QLibraryPrivate*> LibraryMap;Q_GLOBAL_STATIC(LibraryMap, libraryMap)QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, int verNum) :pHnd(0), fileName(canonicalFileName), majorVerNum(verNum), instance(0), qt_version(0), libraryRefCount(1), libraryUnloadCount(1), pluginState(MightBeAPlugin){ libraryMap()->insert(canonicalFileName, this); }QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, int verNum){ QMutexLocker locker(qt_library_mutex()); if (QLibraryPrivate *lib = libraryMap()->value(fileName)) { lib->libraryUnloadCount.ref(); lib->libraryRefCount.ref(); return lib; } return new QLibraryPrivate(fileName, verNum);}QLibraryPrivate::~QLibraryPrivate(){ LibraryMap * const map = libraryMap(); if (map) { QLibraryPrivate *that = map->take(fileName); Q_ASSERT(this == that); Q_UNUSED(that); }}void *QLibraryPrivate::resolve(const char *symbol){ if (!pHnd) return 0; return resolve_sys(symbol);}bool QLibraryPrivate::load(){ if (pHnd) return true; if (fileName.isEmpty()) return false; return load_sys();}bool QLibraryPrivate::unload(){ if (!pHnd) return true; if (!libraryUnloadCount.deref()) // only unload if ALL QLibrary instance wanted to if (unload_sys()) pHnd = 0; return (pHnd == 0);}void QLibraryPrivate::release(){ QMutexLocker locker(qt_library_mutex()); if (!libraryRefCount.deref()) delete this;}bool QLibraryPrivate::loadPlugin(){ if (instance) return true; if (load()) { instance = (QtPluginInstanceFunction)resolve("qt_plugin_instance"); return instance; } return false;}/*! Returns true if \a fileName has a valid suffix for a loadable library; otherwise returns false. \table \header \i Platform \i Valid suffixes \row \i Windows \i \c .dll \row \i Unix/Linux \i \c .so \row \i AIX \i \c .a \row \i HP-UX \i \c .sl \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so \endtable Trailing versioning numbers on Unix are ignored. */bool QLibrary::isLibrary(const QString &fileName){#if defined(Q_OS_WIN32) return fileName.endsWith(QLatin1String(".dll"));#else QString completeSuffix = QFileInfo(fileName).completeSuffix(); if (completeSuffix.isEmpty()) return false; QStringList suffixes = completeSuffix.split(QLatin1Char('.')); QString suffix = suffixes.first();# if defined(Q_OS_DARWIN) // On Mac, libs look like libmylib.1.0.0.dylib const QString lastSuffix = suffixes.at(suffixes.count() - 1); const QString firstSuffix = suffixes.at(0); bool valid = (lastSuffix == QLatin1String("dylib") || firstSuffix == QLatin1String("so") || firstSuffix == QLatin1String("bundle")); return valid;# elif defined(Q_OS_HPUX)/* See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF": "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix." */ bool valid = (suffix == QLatin1String("sl"));# if defined __ia64 valid = valid || (suffix == QLatin1String("so"))# endif# elif defined(Q_OS_AIX) bool valid = (suffix == QLatin1String("a") || suffix == QLatin1String("so"));# elif defined(Q_OS_UNIX) bool valid = (suffix == QLatin1String("so"));# else bool valid = false;# endif for (int i = 1; i < suffixes.count() && valid; ++i) suffixes.at(i).toInt(&valid); return valid;#endif}bool QLibraryPrivate::isPlugin(){ if (pluginState != MightBeAPlugin) return pluginState == IsAPlugin;#ifndef QT_NO_PLUGIN_CHECK bool debug = !QLIBRARY_AS_DEBUG; QByteArray key; bool success = false; QFileInfo fileinfo(fileName);#ifndef QT_NO_DATESTRING lastModified = fileinfo.lastModified().toString(Qt::ISODate);#endif QString regkey = QString::fromLatin1("Qt Plugin Cache %1.%2.%3/%4") .arg((QT_VERSION & 0xff0000) >> 16) .arg((QT_VERSION & 0xff00) >> 8) .arg(QLIBRARY_AS_DEBUG ? QLatin1String("debug") : QLatin1String("false")) .arg(fileName); QStringList reg; QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); reg = settings.value(regkey).toStringList(); if (reg.count() == 4 && lastModified == reg.at(3)) { qt_version = reg.at(0).toUInt(0, 16); debug = bool(reg.at(1).toInt()); key = reg.at(2).toLatin1(); success = qt_version != 0; } else {#if defined(Q_OS_UNIX) if (!pHnd) { // use unix shortcut to avoid loading the library success = qt_unix_query(fileName, &qt_version, &debug, &key, this); } else#endif { bool temporary_load = false; if (!pHnd) temporary_load = load_sys();# ifdef Q_CC_BOR typedef const char * __stdcall (*QtPluginQueryVerificationDataFunction)();# else typedef const char * (*QtPluginQueryVerificationDataFunction)();# endif QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data"); if (!qtPluginQueryVerificationDataFunction || !qt_parse_pattern(qtPluginQueryVerificationDataFunction(), &qt_version, &debug, &key)) { qt_version = 0; key = "unknown"; if (temporary_load) unload_sys(); } else { success = true; } } QStringList queried; queried << QString::number(qt_version,16) << QString::number((int)debug) << QLatin1String(key) << lastModified; settings.setValue(regkey, queried); } if (!success) return false; pluginState = IsNotAPlugin; // be pessimistic if ((qt_version > QT_VERSION) || ((QT_VERSION & 0xff0000) > (qt_version & 0xff0000))) { if (qt_debug_component()) { qWarning("In %s:\n" " Plugin uses incompatible Qt library (%d.%d.%d) [%s]", (const char*) QFile::encodeName(fileName), (qt_version&0xff0000) >> 16, (qt_version&0xff00) >> 8, qt_version&0xff, debug ? "debug" : "release"); } errorString = QLibrary::tr("The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5]") .arg(fileName) .arg((qt_version&0xff0000) >> 16) .arg((qt_version&0xff00) >> 8) .arg(qt_version&0xff) .arg(debug ? QLatin1String("debug") : QLatin1String("release")); } else if (key != QT_BUILD_KEY) { if (qt_debug_component()) { qWarning("In %s:\n" " Plugin uses incompatible Qt library\n" " expected build key \"%s\", got \"%s\"", (const char*) QFile::encodeName(fileName), QT_BUILD_KEY, key.isEmpty() ? "<null>" : (const char *) key); } errorString = QLibrary::tr("The plugin '%1' uses incompatible Qt library." " Expected build key \"%2\", got \"%3\"") .arg(fileName) .arg(QLatin1String(QT_BUILD_KEY)) .arg(key.isEmpty() ? QLatin1String("<null>") : QLatin1String((const char *) key));#ifndef QT_NO_DEBUG_PLUGIN_CHECK } else if(debug != QLIBRARY_AS_DEBUG) { //don't issue a qWarning since we will hopefully find a non-debug? --Sam#endif } else { pluginState = IsAPlugin; } return pluginState == IsAPlugin;#else return pluginState == MightBeAPlugin;#endif}/*! Loads the library and returns true if the library was loaded successfully; otherwise returns false. Since resolve() always calls this function before resolving any symbols it is not necessary to call it explicitly. In some situations you might want the library loaded in advance, in which case you would use this function. \sa unload()*/bool QLibrary::load(){ if (!d) return false; if (did_load) return d->pHnd;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -