2012-02-10 2 views
0

У нас есть набор DLL, написанных на C++ для Windows, которые используются приложением C#, и все это завершается в решении Visual Studio. Теперь кто-то портировал библиотеки DLL на Qt, чтобы их можно было использовать на других ОС. Могу ли я переключиться на Qt-код в своем решении и продолжать работать с приложением C#? Или мне придется разделить на два решения?Могу ли я смешивать проекты Qt и non-Qt в Visual Studio 2010?

Я пытался сделать это уже, но когда я пытаюсь построить я получаю ошибки

«Операция не может быть завершена. Неправильный параметр»

или

«Невозможно выполнить запрошенное действие, поскольку построенный уже находится в прогресс»

FYI, я использую готовые двоичные файлы Qt V4.8.0 для VS2010.

ответ

0

Оказалось, что когда мой коллега сделал порт Qt, он воссоздал некоторые из файлов проекта Visual Studio, в результате чего у них были разные идентификаторы GUID для оригиналов. Когда я переключился на Qt-порт, GUID не совпадали с тем, что были показаны в проектах C# в качестве зависимостей. Visual Studio немного дерьмо при обработке этого (или говорит вам), поэтому вы получаете ошибки, перечисленные выше.

Как только мы исправили это, сборка работала нормально, но работала она ничего не делала - библиотеки C++ DLL никогда не отвечали. В конце концов я понял, что для того, чтобы таймеры Qt и очереди работали, нам пришлось вызывать QCoreApplication внутри DLL, так как мы не использовали Qt UI. Однако, поскольку были некоторые пользовательские интерфейсы Qt, которые использовали одни и те же библиотеки DLL, мы не могли всегда вызывать QCoreApplication, если пользовательский интерфейс уже вызвал QApplication. Вы можете использовать QCoreApplication :: instance(), чтобы проверить, требуется ли вызов, но вы не можете сделать это в DllMain() в DLL_PROCESS_ATTACH, потому что сначала слишком рано, а во-вторых, это зависит от Windows. Таким образом, мы пришли с этим:

static struct Vars 
{ 
    QCoreApplication *l_pQt; 
    bool    l_bQtCoreCreated; 

    Vars() 
     : l_pQt(NULL), l_bQtCoreCreated(false) 
    { 
    } 

    virtual ~Vars() 
    { 
     if (l_pQt != NULL) 
     { 
      if (l_bQtCoreCreated) 
      { 
       delete l_pQt; 
      } 
      l_pQt = NULL; 
      l_bQtCoreCreated = false; 
     } 
    } 
} g_private; 


static void InitQtCore(void) 
{ 
    if (g_private.l_pQt == NULL) 
    { 
     g_private.l_pQt = QCoreApplication::instance(); 
     if (g_private.l_pQt == NULL) 
     { 
      g_private.l_bQtCoreCreated = true; 
      int argc = 0; 
      char *argv = NULL; 
      g_private.l_pQt = new QCoreApplication(argc, &argv); 
     } 
    } 
} 

Любая функция в DLL, что это не просто базовая настройка вызывает InitQtCore() в самом начале. Это отлично работает для Qt и не-Qt UI (C# и C++).

0

У нас есть проект на C++, который включает в себя как библиотеки DLL, созданные с помощью Qt, так и те, которые не знают, что Qt существует. Это прекрасно работает в VS2010, но мы не используем qmake для создания проектов Qt; это MSBUILD, и мы должны специально запускать определенные исполняемые файлы, которые qmake «волшебным образом» выполняется как часть сборки (например, moc).

При этом может быть небольшая разница, поскольку мы создаем собственный набор двоичных файлов на основе коммерческого кода, а не используем предварительно построенные.

Смежные вопросы