Сбой библиотеки DLL Visual Studio C ++ в приложении Qt

У меня проблема с обменом данными «std :: string» между библиотекой MS Visual C ++ DLL и программой Qt.

  • Библиотека DLL написана на Visual C ++ 2010 Express, которая экспортирует один метод:

    extern "C" __declspec(dllexport) int Init(ITest* commandTest);
    
  • Абстрактный интерфейс «ITest» и класс, реализующий его:

    class CTest: public ITest
    {
    public:
    CTest();
    virtual ~CTest();
    virtual void getVersion(std::string & version) const;
    };
    
  • Приложение Qt GUI, которое должно:

    * load the DLL dynamically
    * instantiate CTest and pass it to exported Init method.
    

В DLL «Init» вызывается метод «CTest :: getVersion ()». Я ожидаю, что получит «&версия «заполненная строка. Вместо этого я получаю сбои в строке при заполнении»&версия «с новой строкой.

  • скачал «библиотеки Qt 4.8.3 для Windows (VS 2010, 235 МБ)» с http://qt-project.org/downloads, установил его и выбрал в настройках проекта QtCreator.

  • в QtCreator переключился с инструментария MinGW на тот, что установлен с MS Visual Studio 2010 Express.

    Я думал, что это решит проблему, потому что я использовал библиотеки Qt, скомпилированные с VS 2010, и графический интерфейс Qt был также скомпилирован с помощью инструментальной цепи VS C ++. К сожалению, проблема не исчезла, поэтому я попробовал сделать последний шаг:

  • создал консольное приложение Win32 в Visual Studio, загрузил мою DLL через LoadLibrary, использовал метод «Init» так же, как я делал в Qt GUI … и это сработало !!

Небольшое наблюдение

В «CTest :: getVersion ()» я печатаю эту строку «version», переданную по ссылке на консоль. При использовании консольного приложения VS C ++ оно распечатывается корректно. При использовании приложения Qt — строка «версия» печатается с мусором вокруг (например, ┌►☻qwerty27)

Это заставляет меня думать, что ABI приложения Qt и моей DLL по-прежнему несовместимы даже при использовании библиотек Qt VS 2010, упомянутых выше.

  • Разве использования библиотек Qt для Windows (VS 2010) и инструментария Visual Studio недостаточно для преодоления проблем совместимости ABI?
  • Означает ли это, что я должен скомпилировать каркас Qt самостоятельно?
  • Пожалуйста, помогите — любые идеи приветствуются …

9

Решение

В проекте у меня была ситуация, очень похожая на вашу, две DLL, один и тот же компилятор (VC ++ 2010). Я передавал std :: string от одного к другому и получал много сбоев.

Проблема была в том, что одна DLL была скомпилирована с Многопоточная отладочная DLL (/ MDd) а другой с Многопоточная отладка (/ MTd) это вызвало двоичную несовместимость между двумя библиотеками DLL (происходит сбой).
Также версии должны совпадать, либо использовать DEBUG, либо RELEASE для обеих DLL.

Глядя на ваш проект, обе библиотеки, кажется, используют Многопоточная отладочная DLL (/ MDd). это означает, что оба используют MSVCP100D.dll. Это нормально, единственная проблема в том, что версия Qt для VC ++ с сайта QT скомпилирована в режиме RELEASE и использует MSVCP100.DLL

Я рекомендую изменить вашу библиотеку времени выполнения на Многопоточная DLL (/ MD) для вашей конфигурации DEBUG.

Моя вторая рекомендация состоит в том, чтобы следовать совету и использованию Реберта символ * вместо std :: string. символ * будет совместим, несмотря ни на что.

Вы также можете перекомпилировать QT с Многопоточная отладочная DLL (/ MDd) и используйте эту версию QT для вашей конфигурации DEBUG (но это похоже на большую работу).

1

Другие решения

Номинально я бы не рискнул передавать сложные данные (вне моего контроля, по коду) между приложением и DLL. Я бы прибегнул к передаче только структур POD, то есть вместо этого я бы изменил интерфейс:

class CTest: public ITest
{
public:
CTest();
virtual ~CTest();
virtual void getVersion(char* versionBuffer, unsigned length) const;
};

Делает жизнь намного проще;)

0