90 posts
Edited by C_Worm on
When I change some attributes in the gameCode.cpp it does seem to succesfully reload the DLL during runtime
however, i don't see the changes on screen, that was made in the code.
I want it to reload during runtime.

If i restart the app the changes work, so the problem is just that it doesn't reload during runtime.

I am also using a 3rd party lib (SFML)

any ideas why this problem might occur?

CJsfml_002.cpp
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #define SFML_STATIC #define WIN32_LEAN_AND_MEAN #include #include "SFML\Graphics.hpp" #include float vel = 7.0f; typedef void (*rectFP)(sf::RectangleShape *); int main() { sf::RenderWindow window(sf::VideoMode(960, 540), "SFML works!"); window.setFramerateLimit(60); sf::RectangleShape mRect(sf::Vector2f(40.0f, 40.0f));; mRect.setPosition(sf::Vector2f(30.0f, 30.0f)); mRect.setFillColor(sf::Color::Green); // Getting pointer to the rect sf::RectangleShape *rect = &mRect; while (window.isOpen()) { int count = 125; // Loading DLL CopyFile("gameCode.dll", "temp_gameCode.dll", false); HMODULE hm = LoadLibrary("temp_gameCode.dll"); if(hm) { std::cout << "LOAD LIB SUCCESS!\n"; } // Loading DLL function rectFP rfp = (rectFP)GetProcAddress(hm, "CreateRect"); if(rfp) { std::cout << "load func SUCCESS!\n"; } // Using the DLL function rfp(rect); } // Unloads DLL FreeLibrary(hm); sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(); // Drawing the rect that was changed by the DLL-function window.draw(*rect); window.display(); } return 0; } 

gameCode.h
 1 2 3 4 5 6 7 #define SFML_STATIC #include "SFML\Graphics.hpp" extern "C" { __declspec(dllexport) void CreateRect(sf::RectangleShape *RS); } 

gameCode.cpp
 1 2 3 4 5 6 7 8 #include "gameCode.h" __declspec(dllexport) void CreateRect(sf::RectangleShape *RS) { RS->setSize(sf::Vector2f(100.0f, 200.0f)); RS->setFillColor(sf::Color::Blue); RS->setPosition(sf::Vector2f(100.0f, 100.0f)); } 

build.bat
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @echo off :: IMPORTANT! "=" has to come IMMEDIATLEY after VARIABLE NAME SET compilerSwitches= /MD /EHsc -Zi -nologo SET winLibs= user32.lib gdi32.lib winmm.lib Opengl32.lib ws2_32.lib advapi32.lib SET sfmlDependLibsX64= /LIBPATH:"C:\SFML\SFML-2.5.1_x64\lib" freetype.lib openal32.lib flac.lib vorbisenc.lib vorbisfile.lib vorbis.lib ogg.lib SET sfmlDependLibsX86= /LIBPATH:"C:\SFML\SFML-2.5.1_x86\lib" freetype.lib openal32.lib flac.lib vorbisenc.lib vorbisfile.lib vorbis.lib ogg.lib SET sfmlLibsX64= sfml-system-s.lib sfml-graphics-s.lib sfml-window-s.lib sfml-audio-s.lib sfml-network-s.lib SET sfmlLibsX86= sfml-system-s.lib sfml-graphics-s.lib sfml-window-s.lib sfml-audio-s.lib sfml-network-s.lib If NOT EXIST ..\buildx64 mkdir ..\buildx64 If NOT EXIST ..\buildx86 mkdir ..\buildx86 If NOT EXIST ..\assets mkdir ..\assets pushd ..\buildx64 cl %compilerSwitches% /I ..\include ..\src\CJsfml_002.cpp %winLibs% /link %sfmlDependLibsX64% %sfmlLibsX64% cl %compilerSwitches% /I ..\include ..\src\gameCode.cpp /LD %winLibs% /link %sfmlDependLibsX64% %sfmlLibsX64% popd @echo x64 build Done! ::------------------ x86 BUILD (set vcvarsx86) ----------------- ::pushd ..\buildx86 ::cl /MD /EHsc -Zi -nologo /I ..\include ..\src\CJsfml_002.cpp %winLibs% /link %sfmlDependLibsX86% %sfmlLibsX86% ::popd :: ::@echo x86 build Done! del *.~ *.cpp~ *.bat~ *.un~ *.h~ 
Simon Anciaux
1051 posts
Without the full source it's hard to help you. And the code you posted isn't nested properly.

Are you sure the new dll is copied by CopyFile ? Are you sure the new dll is loaded properly ? Did you try to step in the dll function to see if it's executing the correct code after reloading ? Is rect containing the right values after the call ?
Mārtiņš Možeiko
2198 posts / 1 project
Edited by Mārtiņš Možeiko on
Are you sure call to cl.exe to compile gameCode.dll succeeds? Because it could fail if that happens at same time when CopyFile function is being executed. Verify that cl.exe really succeeds.

Try putting brakpoint on "rfp(rect);" line and do "step in" in the debugger. If dll is rebuild correctly and pdb files are not corrupted you'll be able to step into new code.

Also - you really should be linking to sfml dynamically (dll files), not statically. Because you are using SFML in main exe and in dll as separate copies, but you are passing objects across dll boundaries. This means that some code for objects is called in main .exe but other code for same objects is called in .dll. Depending on situation this may or may not work. Most likely you will get strange crashes later when you'll have a bit more complex code.
90 posts
Edited by C_Worm on
The CopyFile fails with error code 32 (ERROR_ACCESS_VIOLATION).

The first time it calls CopyFile it works, but all times after that it doesn't, becuase im getting access violation, any ideas on how to solve it?

And I am able to step through the rfp(rect) function in the dbugger unless I recompile during runtime.
Simon Anciaux
1051 posts
Either you're copying the source dll while MSVC is writing to it, or you are overwriting "temp_gameCode.dll" while your program still uses it.

After you free the library it may take some time for the file to be released (maybe the debugger also has a handle to the file). Adding Sleep( 250 ); to wait 250 ms before trying to copy the dll worked on a quick test on my machine, but that wouldn't give you a nice frame rate. You should probably only reload the dll when a new one has been compiled.

In handmade hero, Casey does several things to try to avoid problems:
- reload the dll only when it was recompiled, not every frame;
- copy the dll to a different name every time (name_0001.dll, adding 1 each time);
- after freeing the dll, it tries to load the new one (copy the file + load). If it fails (either the copy or load) it wait 100 ms and try again, up to 100 times).
90 posts
Oh gosh!

The problem all along was that I compiled the dll and exe in the wrong order(exe first, then dll), now it seems to work fine!

Thanks
Simon Anciaux
1051 posts