Не могу использовать свою собственную DLL, которая использует SFML

Я делаю свою собственную библиотеку игр, которая использует SFML с VS2013. Я хочу повторно использовать код, установив библиотеку как DLL. Однако у меня возникают проблемы при использовании моей собственной DLL.

Вот подробное описание моей ситуации:

  1. Вот часть кода в игровом цикле, где window — это sf::RenderWindow, а rect — это объект, определенный в моей DLL, который просто представляет собой sf::RectangleShape с определенными свойствами (маленький синий прямоугольник в точке (0,0)).

    window.clear(sf::Color::White);
    window.draw(rect);
    window.display();
    

    Однако после window.draw(rect) весь экран станет черным, даже несмотря на то, что приведенное выше утверждение должно очистить его как белый, а rect занимает лишь небольшое место в верхнем левом углу.

  2. С моим классом не должно быть проблем, так как если я вставлю объявление и определение класса непосредственно в основной исходный файл (конечно, удалив такие вещи, как __declspec(dllexport)), все будет работать хорошо.

  3. Все функции в моей DLL, которые не используют SFML, работают корректно при загрузке из DLL.

  4. SFML статически компонуется как в проекте DLL, так и в проекте, который его использует.

  5. Я просмотрел и следил за MSDN, чтобы настроить свои проекты.

Итак, как это исправить? Я предполагаю, что проблема должна заключаться в том, что я пропустил некоторые шаги, которые позволяют DLL использовать другую библиотеку, но я не нашел соответствующих тем (возможно, я использовал неправильные ключевые слова...)


person Tim Zhang    schedule 06.12.2013    source источник


Ответы (1)


SFML статически компонуется как в проекте DLL, так и в проекте, который его использует.

Если вы действительно статически свяжете SFML с вашей DLL, у вас возникнет проблема, потому что теперь ваше приложение finally содержит копию SFML, а ваша DLL содержит копию SFML. Таким образом, выделенный SFML материал в DLL не обязательно будет доступен в приложении и наоборот.

В качестве решения вы можете связать только все динамическое или все статическое в конечном приложении. Это означает, что вы либо используете динамические библиотеки SFML, либо также связываете свою статическую библиотеку и связываетесь только со статической SFML в своем приложении, а не в своей библиотеке.

Поскольку вы используете VS 2013, вам также придется пересобрать сам SFML, и если вы используете последнюю версию, статическая привязка изменилась (полное обсуждение). Итак, вот несколько рисунков ASCII о том, как это будет работать с SFML 2.0 или 2.1.

             winmm   gdi32   opengl
              /  \     |     /
             /    \    |    /
            v      v   v   v
   sfml-system-s  sfml-window-s
        |  |         |  |
        |  +---------------+      
        |            |  |  |
        |  +---------+  |  |
        |  |            |  |
        v  v            v  v
  example.exe <--- yourlib.dll

С SFML из исходного кода (цель 2.3) это будет выглядеть примерно так.

       sfml-system-s  sfml-window-s  winmm  gdi32  opengl
                |         |           |       |      |
   +------------+ +-------+           |       |      |
   |            | | +-----------------+       |      |
   |  +-----------+ | +-----------------------+      |
   |  |         | | | | +----------------------------+
   |  |         | | | | |
   v  v         v v v v v
yourlib.dll -> example.exe

Однако, по сути, вы хотите следующее:

sfml-system-s  sfml-window-s  winmm  gdi32  opengl  yourlib-s
         |         |           |       |      |       |
         | +-------+           |       |      |       |
         | | +-----------------+       |      |       |
         | | | +-----------------------+      |       |
         | | | | +----------------------------+       |
         | | | | | +----------------------------------+
         | | | | | |
         v v v v v v
         example.exe

Динамическая компоновка по сути работает уже как последняя диаграмма (только другая), поэтому динамическая компоновка отлично работает "из коробки".

В Интернете есть много информации о том, как работают ссылки и т. д. Одним из примеров может быть это сообщение на форуме.

person Lukas    schedule 06.12.2013
comment
Спасибо. Я пробовал связать все динамически, и это работает. Никогда не думал, что это проблема статической компоновки и динамической компоновки... Должен иметь более глубокое понимание того, как работает компоновка. - person Tim Zhang; 06.12.2013
comment
Я рад, что теперь это работает. Я добавил несколько диаграмм, чтобы, возможно, помочь вам понять, что происходит. Также, если вы считаете это ответом, отметьте его как таковой. - person Lukas; 06.12.2013