Russian Qt Forum
Октябрь 01, 2024, 00:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: extern "C" и создание динамической либы, из книги Шлее  (Прочитано 8310 раз)
Hellrider
Гость
« : Январь 26, 2013, 13:57 »

Изучаю создание динамической библиотеки по книге Шлее. В библиотеке содержится одна функция:
Заголовочный файл:

Код:
#ifndef DLL_H
#define DLL_H
#include <QString>
#include "DLL__global.h"

extern "C" {
    QString oddUpper(const QString& str);
}
#endif // DLL_H
Описание:
Код:
#include "dll.h"
QString oddUpper(const QString &str){
    QString strTemp;
    for(int i = 0; i < str.length(); ++i){
        strTemp += (i % 2) ? str.at(i) : str.at(i).toUpper();
    }
    return strTemp;
}
Суть проблемы в том, что при компилировании происходит ошибка:
предупреждение: C4190: для "oddUpper" задана С-компоновка, но возвращаемый тип UDT "QString" несовместим с языком Си

Шлее пишет, что при заключении в extern "C {...} компилятор не будет прикреплять информацию о типе к символьной сигнатуре функции. Без этого спецификатора
компилятор может подставить вместо имени функции совсем другое имя, в котором будет закодирована дополнительная информация.
Подскажите как решить это дело Непонимающий



Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Январь 26, 2013, 14:03 »

Суть проблемы в том, что при компилировании происходит ошибка:
предупреждение: C4190: для "oddUpper" задана С-компоновка, но возвращаемый тип UDT "QString" несовместим с языком Си

Шлее пишет, что при заключении в extern "C {...} компилятор не будет прикреплять информацию о типе к символьной сигнатуре функции. Без этого спецификатора
компилятор может подставить вместо имени функции совсем другое имя, в котором будет закодирована дополнительная информация.
Подскажите как решить это дело Непонимающий
Компилятор тебя предупреждает, что функцию oddUpper ты декларируешь как С-функцию, но в качестве параметра и типа возвращаемого значения указываешь классы. Эта функция oddUpper не сможет работать с объектами классов.

Либо не используй классы для этой функции, либо убери extern "C" и компилятор заманглит имя этой функции.
« Последнее редактирование: Январь 26, 2013, 14:05 от Old » Записан
Hellrider
Гость
« Ответ #2 : Январь 26, 2013, 14:37 »

Суть проблемы в том, что при компилировании происходит ошибка:
предупреждение: C4190: для "oddUpper" задана С-компоновка, но возвращаемый тип UDT "QString" несовместим с языком Си

Шлее пишет, что при заключении в extern "C {...} компилятор не будет прикреплять информацию о типе к символьной сигнатуре функции. Без этого спецификатора
компилятор может подставить вместо имени функции совсем другое имя, в котором будет закодирована дополнительная информация.
Подскажите как решить это дело Непонимающий
Компилятор тебя предупреждает, что функцию oddUpper ты декларируешь как С-функцию, но в качестве параметра и типа возвращаемого значения указываешь классы. Эта функция oddUpper не сможет работать с объектами классов.

Либо не используй классы для этой функции, либо убери extern "C" и компилятор заманглит имя этой функции.


Я убрал  extern "C". Скомпилировал. Подключил готовый dll к приложению:

Код:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QLabel lbl("this is example text");

    QLibrary lib("DLL_");

    typedef QString (*Fct)(const QString&);
    Fct fct = (Fct)(lib.resolve("oddUpper"));
    if(fct){
        lbl.setText(fct(lbl.text()));
    }
    lbl.show();

   
    return a.exec();
}
Библиотека подключается, но функция которая в библиотеке не выполняется. Помогите разобраться, раз Шлее вместо того что бы просвятить - запутывает новичков  Смеющийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Январь 26, 2013, 14:42 »

Библиотека подключается, но функция которая в библиотеке не выполняется. Помогите разобраться, раз Шлее вместо того что бы просвятить - запутывает новичков  Смеющийся
Боюсь, что имя у этой функции теперь не такое простое. Улыбающийся

Ладно, если хочешь иметь не мангленное имя, то возвращай extern "C" и вместо QString используй char*.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Январь 26, 2013, 14:53 »

Проще всего возвратить ссылку или указатель на QString (вместо значения). А "по всем правилам" - класс QString должен быть объявлен "импортируемым" в либе и "экспортируемым" в приложении. Однако я уже успел забыть подробности, поэтому лучше сам послушаю  Улыбающийся
Записан
Hellrider
Гость
« Ответ #5 : Январь 26, 2013, 14:57 »

Библиотека подключается, но функция которая в библиотеке не выполняется. Помогите разобраться, раз Шлее вместо того что бы просвятить - запутывает новичков  Смеющийся
Боюсь, что имя у этой функции теперь не такое простое. Улыбающийся

Ладно, если хочешь иметь не мангленное имя, то возвращай extern "C" и вместо QString используй char*.


Ну я над этим думал, можно конечно и через char*. Но уверен, должен быть способ для изначального варианта.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Январь 26, 2013, 14:59 »

Ну я над этим думал, можно конечно и через char*. Но уверен, должен быть способ для изначального варианта.
Тогда не обращай внимание на варнинг. Улыбающийся
Записан
Hellrider
Гость
« Ответ #7 : Январь 26, 2013, 15:38 »

Проще всего возвратить ссылку или указатель на QString (вместо значения). А "по всем правилам" - класс QString должен быть объявлен "импортируемым" в либе и "экспортируемым" в приложении. Однако я уже успел забыть подробности, поэтому лучше сам послушаю  Улыбающийся

Тоже хочу послушать об этом  Строит глазки
Записан
Hellrider
Гость
« Ответ #8 : Январь 28, 2013, 14:49 »

Неужели никто не знает как это делается правильно? Помогите. Я перелопатил инфу об этом и вообще запутался теперь  Непонимающий. Знаю точно, что нужно использовать макросы или типа того, для
импорта/експорта (в случае с виндой и компилятором msvs). Но как правильно реализовать не осиливаю.
Записан
Bepec
Гость
« Ответ #9 : Январь 28, 2013, 15:00 »

Кхм. Я не совсем понимайт о чем вы гаварийтен, но не это ли вы ищете?

Код:
#ifdef MYCLASS_LIB
# define MYCLASS_EXPORT Q_DECL_EXPORT
#else
# define MYCLASS_EXPORT Q_DECL_IMPORT
#endif

class MYCLASS_EXPORT QtAddonSB
{
Записан
Hellrider
Гость
« Ответ #10 : Январь 28, 2013, 15:23 »

Кхм. Я не совсем понимайт о чем вы гаварийтен, но не это ли вы ищете?

Код:
#ifdef MYCLASS_LIB
# define MYCLASS_EXPORT Q_DECL_EXPORT
#else
# define MYCLASS_EXPORT Q_DECL_IMPORT
#endif

class MYCLASS_EXPORT QtAddonSB
{

Это оно, при создании библиотеки в QtCreator создается отдельный заголовочный файл и там это находится. Но как правильно реализовать...
Что-то типа
Код:
#ifndef DLL_H
#define DLL_H
#include <QString>
#include "DLL__global.h" //заголовочный файл с дефайнами

MYCLASS_EXPORT QString oddUpper(const QString& str);

#endif // DLL_H

А как в самом приложении подключать? Или это изначально не правильно? И нужно ли заключать обявление функции в extern "C"?
-----------------------------
Заключил в extern "C" и добавил макрос - заработало.
« Последнее редактирование: Январь 28, 2013, 15:47 от Hellrider » Записан
twp
Гость
« Ответ #11 : Январь 29, 2013, 16:05 »

как раз по теме вопроса: How to create a library with Qt and use it in an application
Записан
Hellrider
Гость
« Ответ #12 : Январь 29, 2013, 22:33 »

как раз по теме вопроса: How to create a library with Qt and use it in an application

Да это я нашел еще в начале своих изысканий  Смеющийся, там даже по-русски есть. Но голова упорно сопротивлялась понимать.
Записан
Bepec
Гость
« Ответ #13 : Январь 30, 2013, 08:12 »

Что тут непонятного?
Код:
    #include <QtGui>
     
    #if defined TEST
    #define TEST_COMMON_DLLSPEC  Q_DECL_EXPORT
    #else
    #define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
    #endif
     
    extern "C" TEST_COMMON_DLLSPEC QWidget* createWidget1();
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.071 секунд. Запросов: 19.