Название: Миграция с MinGW на MSVC2015 Отправлено: Николай от Июнь 28, 2016, 17:06 Добрый день всем!
Пытаюсь перевести проект (динамическую библиотеку) с MinGW на MSVC2015. На MinGW никаких проблем не было. На MCVC2015 при сборке сыпется предупреждениями и ошибками: Цитировать предупреждение: C4190: 'getVersion' has C-linkage specified, but returns UDT 'QString' which is incompatible with C предупреждение: C4190: 'selectDates4Report' has C-linkage specified, but returns UDT 'QStringList' which is incompatible with C ошибка: C2526: 'selectDepts': C linkage function cannot return C++ class 'QList<QList<QString>>' предупреждение: C4190: 'drawGraph' has C-linkage specified, but returns UDT 'QImage' which is incompatible with C .pro Код: greaterThan(QT_MAJOR_VERSION, 4) { .h Код:
Прошу помощи. Буду рад любой полезной информации Название: Re: Миграция с MinGW на MSVC2015 Отправлено: ssoft от Июнь 28, 2016, 17:39 extern "C" явно лишняя, так как в чистом Си отсутствуют шаблоны и классы.
MinGW игнорирует эту запись, а MSVC - нет. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Николай от Июнь 29, 2016, 14:11 extern "C" явно лишняя, так как в чистом Си отсутствуют шаблоны и классы. MinGW игнорирует эту запись, а MSVC - нет. https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application/ru (https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application/ru) Цитировать QLibrary может использоваться для загрузки разделяемых библиотек в момент выполнения. В этом случае достаточно иметь доступ только к .dll, доступ к заголовкам и .lib файлу(ам) не требуется. Следующий пример показывает, как установить библиотеку для использования с QLibrary. Для разрешения имен функций, они должны быть экспортированы из библиотеки как C функции (т.е. без искажения имени). Это означает, что функции должны быть обернуты в блок extern "C", в случае если библиотека скомпилирована компилятором C. Или это к MSVC не относится, так это C++, а не C? Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Igors от Июнь 29, 2016, 14:58 extern "C" нужно если Вы хотите сами находить/дергать ф-ции по имени (в примере library.resolve("createWidget1").
Обычно необходимости в этом нет. Убираете extern C и просто компилите библиотеку. Получаете (помимо dll) небольшой lib файл (фактически обертку), вот его подключаете к проекту который использует либу. Цитировать предупреждение: C4190: 'selectDates4Report' has C-linkage specified, but returns UDT 'QStringList' which is incompatible with C Такие предупреждения надо все убрать, обычно они означают crash на выполненииНазвание: Re: Миграция с MinGW на MSVC2015 Отправлено: Old от Июнь 29, 2016, 16:36 extern "C" нужно если Вы хотите сами находить/дергать ф-ции по имени (в примере library.resolve("createWidget1"). Нет. extern "C" указывает компилятору использовать сишный манглинг имен, вместо плюсового (в котором кодируются и аргументы).Находить и дергать можно любые экспортируемые функции, что сишные, что плюсовые. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Николай от Июнь 29, 2016, 17:05 extern "C" нужно если Вы хотите сами находить/дергать ф-ции по имени (в примере library.resolve("createWidget1"). Обычно необходимости в этом нет. Убираете extern C и просто компилите библиотеку. Получаете (помимо dll) небольшой lib файл (фактически обертку), вот его подключаете к проекту который использует либу. Цитировать предупреждение: C4190: 'selectDates4Report' has C-linkage specified, but returns UDT 'QStringList' which is incompatible with C Такие предупреждения надо все убрать, обычно они означают crash на выполненииСпасибо за совет, но я использую QLibrary для загрузки этой разделяемой библиотеки вот таким образом: Цитировать QLibrary lib(qApp->applicationDirPath()+QDir::separator()+"rsrcs"); if(lib.load()) { typedef const QList <QList<QString> > (*MyClass)(const QStringList &,bool,bool,int,QWidget *,Qt::WindowState); MyClass myFunction = (MyClass) lib.resolve("selectDepts"); if(myFunction) {...} } И если убрать extern "C" функция просто не вызывается, т.е. lib.resolve("selectDepts") не находит указанную процедуру :( можно ли как-то заставить MSVC не ругаться на QList<QList<QString>> и на возврат результата формате QImage в функции drawGraph? Цитировать C linkage function cannot return C++ class 'QList<QList<QString>> Цитировать 'drawGraph' has C-linkage specified, but returns UDT 'QImage' which is incompatible with C Подскажите, как правильно писать такие вещи? Название: Re: Миграция с MinGW на MSVC2015 Отправлено: kuzulis от Июнь 29, 2016, 18:33 Эмм... для этих целей используют плагины.
Название: Re: Миграция с MinGW на MSVC2015 Отправлено: kai666_73 от Июнь 30, 2016, 01:20 Вах :o
Kaкие нафиг QLibrary, какие плагины? Igors верно глаголит... Случай простейший - есть все необходимые исходники. Все что нужно - это собрать библиотеку с необходимыми экспортируемыми функциями и использовать эту библиотеку без всяких выкрутасов. Соответственно, все extern "С" из библиотеки надо повыпиливать, а мудренные вызывы библиотечных функций заменить просто вызовами... Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Old от Июнь 30, 2016, 05:56 Kaкие нафиг QLibrary, какие плагины? А если реализаций этих функций несколько и для работы нужно загружать определенную, в зависимости от каких-то параметров?Все что нужно - это собрать библиотеку с необходимыми экспортируемыми функциями и использовать эту библиотеку без всяких выкрутасов. Вот у ТС похоже такая ситуация (судя по первой функции getVersion). К сожалению ему нужно для msvc, а опускаться до этого нет никакого желания. Возможно, проще будет действительно реализовать это как систему плагинов, которые экспортируют единственную функцию, конструирующую объект и возвращающую указатель на него. А все эти функции будут методами. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: kuzulis от Июнь 30, 2016, 08:23 Цитировать Kaкие нафиг QLibrary, какие плагины? 1. Если грузить нужно динамически либу - в этом случае лучше именно плагины. 2. Если можно не грузить при помощи QLibrary, а линковатся - в этом случае достаточно import/export без всяких extern C. PS: Как-бы ТС упоминал только о QLibrary => 1й вариант предпочтительнее... о линковке речи не было. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Николай от Июнь 30, 2016, 08:39 Kaкие нафиг QLibrary, какие плагины? А если реализаций этих функций несколько и для работы нужно загружать определенную, в зависимости от каких-то параметров?Все что нужно - это собрать библиотеку с необходимыми экспортируемыми функциями и использовать эту библиотеку без всяких выкрутасов. Вот у ТС похоже такая ситуация (судя по первой функции getVersion). К сожалению ему нужно для msvc, а опускаться до этого нет никакого желания. Возможно, проще будет действительно реализовать это как систему плагинов, которые экспортируют единственную функцию, конструирующую объект и возвращающую указатель на него. А все эти функции будут методами. Именно так. Я портирую проект с Qt 4.8 на Qt 5.7. С MinGW проблем не было ни на windows, ни на linux. Но в проекте кое-где использовался QHttp, который в Qt5x выпилили, а WebEngine не поддерживается MinGW. Отсюда и необходимость перехода с MinGW на MSVC2015. В проекте итак используется плагинная система. есть основное ядро и есть плагины. Функции данной библиотеки должны дергаться и ядром и плагинами. Поэтому и вынесены в отдельную dll. А вызывать из плагина другой плагин как-то не эстетично же). Вот здесь описан же способ Using QLibrary to load the shared library http://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application (http://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application) и пока сидел на mingw все работало как надо. И в чем сейчас затык с mcvc2105 не могу понять :( Цитата: Old К сожалению ему нужно для msvc, а опускаться до этого нет никакого желания А чем плох этот C++ компилятор из Visual Studio 2015? И какие есть альтернативы тогда?Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Racheengel от Июнь 30, 2016, 09:07 У нас в заголовках дллок используется такое решение:
#if defined _MSC_VER || defined __MINGW32__ || defined __MINGW64__ #define I_FUNCTION_EXPORT __declspec(dllexport) #elif defined __GNUC__ #define I_FUNCTION_EXPORT __attribute__ ((visibility("default"))) #else #define I_FUNCTION_EXPORT #endif И каждый класс помечается как I_FUNCTION_EXPORT. Но вообще __declspec(dllexport) это грязный хак от микрософта, по хорошему компилятор должен сам понимать, что экспортировать, а что нет. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Igors от Июнь 30, 2016, 09:12 Спасибо за совет, но я использую QLibrary для загрузки этой разделяемой библиотеки вот таким образом: Ну хорошо, допустим надо "только так" (по имени). Тогда вместо selectDepts надо подставить "mangled" имя. Откомпилите dll (без extern C) и посмотрите список экспортируемых ф-ций напр с помощью depends.exe. Там должно быть какое-то калечное/накрученое, но содержащее selectDepts - вот его и подставьте в resolveЦитировать QLibrary lib(qApp->applicationDirPath()+QDir::separator()+"rsrcs"); if(lib.load()) { typedef const QList <QList<QString> > (*MyClass)(const QStringList &,bool,bool,int,QWidget *,Qt::WindowState); MyClass myFunction = (MyClass) lib.resolve("selectDepts"); if(myFunction) {...} } И если убрать extern "C" функция просто не вызывается, т.е. lib.resolve("selectDepts") не находит указанную процедуру :( Это конечно коряво, но иначе надо менять вызовы чтобы не было возврата структур, напр так Код Что не смертельно (хотя и неприятно) Подскажите, как правильно писать такие вещи? Насколько помню, стандарт не регламентирует поведение определяемое типом линковки, т.е. MSVC имеет право на свою реализацию/правила.Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Old от Июнь 30, 2016, 09:14 Функции данной библиотеки должны дергаться и ядром и плагинами. Поэтому и вынесены в отдельную dll. Тогда вы их можете оформить как экспортируемые и подключать эту библиотеку как я ядру, так и к плагинам. Никакой ручной загрузки и поиска точек входа не понадобиться.А вызывать из плагина другой плагин как-то не эстетично же). Посмотрите на QtCreator. :)А чем плох этот C++ компилятор из Visual Studio 2015? И какие есть альтернативы тогда? Тем, что он не умеет в современный C++ и вообще кладет на стандарты.А альтернативы те-же - MinGW или еще можно интеловский компилятор попробовать. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Racheengel от Июнь 30, 2016, 10:49 Интел дорого, МинГВ медленный и капризный.
Студия экспресс довольно быстрая и оптимирует неплохо. И с++11 она понимает. Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Old от Июнь 30, 2016, 11:18 И с++11 она понимает. Ну слава Богу... 2016 год на дворе. :)Название: Re: Миграция с MinGW на MSVC2015 Отправлено: kai666_73 от Июнь 30, 2016, 12:17 А теперь Old истину глаголит.
Линкуйте библиотеку к основному коду и к плагинам, которые ее используют; и будет вам счастье :) Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Igors от Июнь 30, 2016, 13:18 Линкуйте библиотеку к основному коду и к плагинам, которые ее используют; и будет вам счастье :) Цитировать Грузите апельсины бочками Братья Карамазовы Название: Re: Миграция с MinGW на MSVC2015 Отправлено: Akon от Июль 15, 2016, 15:03 ... А это очевидно? Допустим, длл имеет файл 'unit1.c', в котором есть пара функцийНо вообще __declspec(dllexport) это грязный хак от микрософта, по хорошему компилятор должен сам понимать, что экспортировать, а что нет. Код: int foo_public() { return 0; } __declspec(dllimport) также служит для оптимизации - генерирует более эффективный косвенный вызов в одну инструкцию Код: call DWORD PTR __imp_foo_public ; __imp_foo_public - слот в секции импорта приложения |