I have created a simple RAII class in one of my DLLs (let's call it the exporting DLL) which monitors for configuration restore in my application:
Header file
class __declspec(dllexport) CEmuConfigurationRestoreMonitor
{
public:
CEmuConfigurationRestoreMonitor()
{
m_restoreInProgress = true;
}
~CEmuConfigurationRestoreMonitor()
{
m_restoreInProgress = false;
}
static bool IsRestoreInProgress()
{
return m_restoreInProgress;
}
private:
static bool m_restoreInProgress;
};
Source file
bool CEmuConfigurationRestoreMonitor::m_restoreInProgress = false;
The idea is that the restore code in the exporting DLL will instantiate a CEmuConfigurationRestoreMonitor on the stack and when it goes out of scope at the end of the method, the flag will be switched off.
The problem is that I want to query the flag, using IsRestoreInProgress(), from another DLL (let's say the importing DLL). This is why I put __declspec(dllexport) in the class declaration in the exporting DLL.
When I link the importing DLL, I got an unresolved symbol for m_restoreInProgress. So I added the following line to a .cpp file in the importing DLL and it fixes that issue:
bool CEmuConfigurationRestoreMonitor::m_restoreInProgress = false;
What I am finding now is that even if m_restoreInProgress is set to true, when I query it from the importing DLL, it's always returning false.
Is the static initialization in the importing DLL somehow overriding the real (current) value in the exporting DLL?
You've given each DLL its own copy of m_restoreInProgress.
You could fix this by:
Not using an inline function.
Using a file-scoped variable for m_resotreInProgress, in a source file included in only the exporting DLL.
Related
I come to submit a problem I have while trying to import symbols from static library implicitly.
Let me set up the problem with a peace of simplified code:
I have 3 projects:
- a static plugin handler project that defines a registry class, it is linked in the other two projects
- a static plugin project
- a final project that has a plugin handler and "load statically" the plugin.
first, the static plugin handler project:
struct PluginType
{
virtual void doMyStuff() = 0 ;
};
typedef PluginType* (*PluginCreator)();
struct Registry
{
std::map<std::string, PluginCreator> _item_list;
static Registry& instance()
{
static Registry singleton;
return singleton;
}
static PluginType* create(std::string const& name)
{
// call the creator function that returns an PluginType*
return instance()[name]();
}
};
struct RecordInRegistry
{
RecordInRegistry(std::string const& key, PluginCreator new_item_creator)
{
Registry::instance()._item_list[key] = new_item_creator;
}
};
Now, a static plugin project
struct ADerivedItem : public PluginType
{
virtual void doMyStuff() override
{
//some really interesting stuffs
}
static PluginType* create() { return new ADerivedItem() ; }
}
export "C" const RecordInRegistry i_record_derived_item_class("derived_item", &ADerivedItem::create);
Then, the final project where i use the plugin. This project links the two other porjects !
int main()
{
PluginType* my_instance = Registry::create("derived_item");
return 0;
}
What I hope is that I will be able to register my static plugin just by linking the static library plugin
to the project.
It almost worked ! The only problem I got is that the symbol "i_record_derived_item_class" from the static
plugin is not explicitly used in the final project, thus this symbol is not imported from the static plugin lib !
I work on visual studio, i found a simple fix that consists in forcing the symbol import, something like
/INCLUDE:i_record_derived_item_class, and everything works fine.
I want to know if you see a work around to this, what I would like is to be able to add this kind of static
plung just by linking it, without having to add anything more than /LINK:myStaticPlugin.lib
Any idea ?
Moreover it would be really nice to avoid MSVC-specific solution.
Thanks in advance !
The problem is that symbols in library are used only when required. Draft n4659 says at 5.2 Phases of translation [lex.phases]:
All external entity references are resolved. Library components are linked to satisfy external references
to entities not defined in the current translation.
As your current source has no external references to i_record_derived_item_class, nor to the class ADerivedItem, nothing will be loaded by default from the plugin project. Worse, even the plugin handler module has no reference either, so you need to declare an undefined reference to the build system itself, be it MSVC or anything else.
Alternatively, you could link a minimal translation unit (means a .cpp or .o file) containing an external reference to i_record_derived_item_class, to force the resolution from a library.
I want to call this delphi code via a DLL from C++
procedure MyMessage; stdcall;
begin
ShowMessage(DLLName + ' more text');
end;
Using some delphi test code I see no problem , but from C++ no message box is shown.
i did the following C++ coding
// function prototype
typedef void(__stdcall*VoidCall)();
// prototype for info function inside DLL
extern "C" __declspec(dllimport) void __stdcall MyMessage();
MyMessage = (VoidCall)::GetProcAddress(load, "MyMessage");
MyMessage;
As I want to use as a next steps existing delphi forms with a wrapper DLL from C++ , I guess the solution of this problem will also enable me for the next task ....
The presented C++ code does not compile. It mixes binding of a dll via an import library with dynamic loading of a dll via LoadLibrary / GetProcAddress.
To load a DLL created with Delphi, it is easiest to use dynamic loading of the dll. Do this as follows:
// function prototype
typedef void(__stdcall*VoidCall)();
[...]
// Load the library
HMODULE lib = LoadLibrary("Project1.dll");
if (lib != 0)
{
__try
{
// Get the address to the exported function in the DLL
// and store it in the variable myMessageFunction
VoidCall myMessageFunction = (VoidCall) GetProcAddress(lib, "MyMessage");
// Call the function. Note you need the parenthesis even
// when there are no parameters to pass
myMessageFunction();
}
__finally
{
// Unload the library again. Note that you cannot use
// functions from the library after that. So only unload
// the dll once you don't need it anymore.
FreeLibrary(lib);
}
}
else // TODO: Error handling, dll cannot be loaded
If you want to use load time linking, you can create a *.lib file to be used with C++ for a DLL created with Delphi. Use the solution from this question.
Update: I ended up getting this work by using DLLs and loading and unloading them. https://www.youtube.com/watch?v=mFSv0tf6Vwc
I know its possible because I've seen posts about this but i don't really understand them.
So i have class(DetailsLayout) that calls a method in another class(Components). At runtime i change the contents of Components to add another component that the user created to that method. I want to recompile the DetailsLayout.cpp and the Components.h but i'm confused as to how to go about this.
right now i'm trying this because of this post : Using G++ to compile multiple .cpp and .h files
system(("g++ -c ProjectComponents.hpp").c_str());
system(("g++ -c DetailsLayout.cpp").c_str());
DetailsLayout::CreateMenu();
I get an error that says g++ is not recognized as an internal or external command.
as per Jesper's suggestion ill mention what id like my end goal to be. So right now in my Game Engine i allow users to add components (that i made) to objects in the scene dynamically. When i tried to make it so that the "user" can make a component and add it dynamically i couldn't do it unless i compiled the .h and .cpp file i made for them. If i manually include the file into my project and run the method for adding the class it works but i want that to happen when i click a button for compiling.
My Components all inherit from this class.
class Component
{
public:
Component();
~Component();
virtual bool Initialize() { return true; }
virtual bool Update(float dt) { dt; return true; }
virtual bool Draw() { return true; }
template <class T> T* GetSiblingComponent()
{
return m_owner->GetComponentByType<T>();
}
protected:
Entity* m_owner;
char m_name[Imgn::MAX_NAME_LEN];
bool m_enabled;
};
I get an error that says g++ is not recognized as an internal or external command.
Well, it's not guaranteed that GCC is installed at your target machine. You have to ensure that in first place if you want to compile and run your code at arbitrary host machines.
Also you seem to miss the linking stage, and calling the resulting executable as well.
I was searching through stackoverflow questions but none of them answered my question. I have a game engine and I want to load player AI (written in c++) in runtime.
Click on button, file dialog appears
Choose file with AI (.dll or something?)
Click on 'start' button, game starts using AI's that I add.
AI could be a method or whole class, it doesn't matter. I think I should generate .dll but I not sure how to do that. This class should look like this:
class PlayerAI
{
void computeSomething(list of argument, Object& output)
{
// some logic
}
}
Assuming pure Windows platform since none specified -
If you want to inject DLL, first obtain a handle to it using LoadLibrary-function like so:
HINSTANCE handleLib;
handleLib = LoadLibrary(TEXT("YourDLL.dll"));
You may then obtain a function pointer to a specific function in the lib. Like this:
FUNC_PTR func;
func = (FUNC_PTR) GetProcAddress(handleLib, "yourFunc");
Then you can call the function like so:
(func) (L"TESTSTRING HERE");
When done, call FreeLibrary(libhandle)
How to declare a function as exported is in VS for instance like this (this is needed to mark your function in your DLL that you precompile:
__declspec(dllexport) int __cdecl yourFunc(LPWSTR someString)
{
//Code here...
}
Since you mention already compiled DLLs, you want to look at LoadLibrary and GetProcAddress. That's how you do runtime loads of DLLs and extract specific functions from them.
Examples can be found under Using Run-Time Dynamic Linking.
I have created a project that uses 2 DLL's to play against each other (a DLL is a player). The game is that the first player picks a number and the second player picks another number, and then the PlayRound function compares the two numbers. My problem that am not sure how to load the DLL (run/load time). I created my first DLL (simple.dll) which has a Pick function that always returns "int 2" for simplicity:
#include "stdafx.h"
#define ASEXPORT
#include <iostream>
#include "player.h"
using namespace std;
int Pick(int Round, int MyMoves[], int OpponentMoves[])
{
return 2;
}
This project have a header (player.h) with the following code:
#ifndef ASEXPORT
#define DLLIMPORTOREXPORT dllimport
#else
#define DLLIMPORTOREXPORT dllexport
#endif
_declspec(DLLIMPORTOREXPORT) int Pick(int Round, int MyMoves[], int OpponentMoves[]);
Not sure where to include this code do i include it in the main or in a function:
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
//hinstLib = LoadLibrary(TEXT(player2Name));
hinstLib = LoadLibrary();
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "simple.DLL");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// Report any failures
if (! fRunTimeLinkSuccess)
printf("Unable to load DLL or link to functions\n");
if (! fFreeResult)
printf("Unable to unload DLL\n");
//
I hope I made it easy to understand
You can see this in my ModuleService implementation in the IndieZen core library. I treat .dll and .so as a "module". In my plugin system I have a standard that every module implements one and only one exported function, which is getModule() in my example, Pick() in your use case.
My example returns in implementation of I_Module interface. In my example, modules are collections of plugins, so the only thing you can do is get an implementation of an I_Plugin, which in turn can be used to gain access to class factories, and then these class factories construct objects (extensions) which implement pre-defined interfaces (extension points).
I know that's all overkill for your example, but the code is quite easy to follow; feel free to copy/paste the subsets you can use.
One key thing is to NOT use _declspec(DLLIMPORTOREXPORT) on the Pick function; you should only be exporting the function and not importing it. You should also not be linking these DLL's to your main application, nor should you include the DLL's header file into your main application. This will give you the flexibility of being able to import two separate DLL's that expose the same function (Pick in your case) without having linking errors. It will also give you the advantage of not knowing the names of the DLL's until runtime (where possibly you may want some configuration or GUI to let the user pick which players).
My implementation, with the reference counting, class factory, etc would give you an added advantage in that you could have two players implemented within the same DLL which could play against each other.