我正在创建自己的游戏库,它使用SFML和VS2013。我想通过将库设置为DLL来重用代码。但是,我在使用自己的DLL时遇到了麻烦。
以下是我的具体情况的详细说明:
以下是游戏循环中代码的一部分,其中window
是sf::RenderWindow
而rect
是我的DLL中定义的对象,它只是{{1}具有已定义的属性((0,0)处的小蓝色矩形)。
sf::RectangleShape
然而,在window.clear(sf::Color::White);
window.draw(rect);
window.display();
之后,整个屏幕将变成黑色,即使上面的语句应将其清除为白色,window.draw(rect)
仅占据左上角的一个小位置。
我的课应该没有问题,因为如果我将类声明和定义直接粘贴到主源文件中(当然删除像rect
这样的东西),一切都很好用。
从DLL加载时,我的DLL中所有不使用SFML的函数都能正常工作。
SFML在DLL项目和使用它的项目中都是静态链接的。
我查看并关注MSDN来设置我的项目。
那么如何解决呢?我想问题应该是我错过了一些允许DLL使用另一个库的步骤,但我没有找到相关的线程(可能我使用了错误的关键字......)
答案 0 :(得分:4)
SFML在DLL项目和使用它的项目中都是静态链接的。
如果您确实将SFML静态链接到您的DLL,那么您将遇到问题,因为现在您的finally应用程序保存了SFML的副本,并且您的DLL保存了SFML的副本。因此,SFML在DLL中分配的东西不一定在应用程序中可用,反之亦然。
作为一种解决方案,您只能在最终应用程序中链接动态或静态的所有内容。这意味着你要么使用SFML的动态库,要么链接你的库静态,并且只链接到应用程序中的SFML静态而不是库中。
由于您使用的是VS 2013,因此您还必须重建SFML本身,如果使用最新版本,则静态链接已更改(full discussion)。所以这里有一些关于如何使用SFML 2.0或2.1的ASCII艺术。
winmm gdi32 opengl
/ \ | /
/ \ | /
v v v v
sfml-system-s sfml-window-s
| | | |
| +---------------+
| | | |
| +---------+ | |
| | | |
v v v v
example.exe <--- yourlib.dll
使用来自源(目标2.3)的SFML,它看起来像这样。
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
动态链接本质上已经像最后一个图表一样工作(只是不同),因此动态链接工作正常“开箱即用”。
网上有很多关于链接工作的信息等等。一个例子是this forum post。