C++ Dynamically load arbitrary function from DLL into std::function - c++

How can I load an arbitrary dynamic-link library (dll) function into a std::function object using a single function?
For example I would like to compile two functions into a dll:
// test.dll
int plusFive(int value) {
return value + 5;
}
void printHello() {
std::cout << "Hello!" << std::endl;
}
And load them both at runtime using a single function like this:
// main.cc
#include <functional>
int main() {
std::function<int(int)> func1(loadDllFunc("test.dll", "plusFive"));
std::function<void()> func2(loadDllFunc("test.dll", "printHello"));
}

Use the WinAPI functions provided in windows.h (descriptions taken from MSDN Dev Center).
LoadLibrary - Loads the specified module into the address space of the calling process. Returns a handle to the module.
GetProcAddress - Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). Returns the address of the exported function or variable.
Use this function to load a specific function and return a std::function object:
// main.cc
#include <iostream>
#include <string>
#include <functional>
#include <windows.h>
template <typename T>
std::function<T> loadDllFunc(const std::string& dllName, const std::string& funcName) {
// Load DLL.
HINSTANCE hGetProcIDDLL = LoadLibrary(dllName.c_str());
// Check if DLL is loaded.
if (hGetProcIDDLL == NULL) {
std::cerr << "Could not load DLL \"" << dllName << "\"" << std::endl;
exit(EXIT_FAILURE);
}
// Locate function in DLL.
FARPROC lpfnGetProcessID = GetProcAddress(hGetProcIDDLL, funcName.c_str());
// Check if function was located.
if (!lpfnGetProcessID) {
std::cerr << "Could not locate the function \"" << funcName << "\" in DLL\"" << dllName << "\"" << std::endl;
exit(EXIT_FAILURE);
}
// Create function object from function pointer.
std::function<T> func(reinterpret_cast<__stdcall T*>(lpfnGetProcessID));
return func;
}
The DLL source should be written like this:
// test.cc (test.dll)
#include <iostream>
// Declare function prototypes with "extern C" to prevent name mangling.
// Declare functions using __declspec(dllexport) to signify the intent to export.
extern "C" {
__declspec(dllexport) int __stdcall plusFive(int);
__declspec(dllexport) void __stdcall printHello();
}
int plusFive(int value) {
return value + 5;
}
void printHello() {
std::cout << "Hello!" << std::endl;
}
And then use loadDllFunc like this:
// main.cc
int main() {
auto func1 = loadDllFunc<int(int)>("test.dll", "plusFive");
auto func2 = loadDllFunc<void()>("test.dll", "printHello");
std::cout << "Result of func1: " << func1(1) << std::endl;
func2();
}
Output:
Result of func1: 6
Hello!
As a sidenote the DLL can be compiled using GCC (4.7.2) like this:
g++ -shared -o test.dll test.cc -std=c++11
Edit:
I'm not sure that the cast in loadDllFunc gives the correct type:
std::function<T> func(reinterpret_cast<__stdcall T*>(lpfnGetProcessID));
It seems to cast it to __stdcall int (*)(int) when it should be int (__stdcall *)(int).
Here is another way to implement loadDllFunc using an auxiliary parser class. This solution will correctly cast the function pointer to int (__stdcall *)(int).
template <typename T>
struct TypeParser {};
template <typename Ret, typename... Args>
struct TypeParser<Ret(Args...)> {
static std::function<Ret(Args...)> createFunction(const FARPROC lpfnGetProcessID) {
return std::function<Ret(Args...)>(reinterpret_cast<Ret (__stdcall *)(Args...)>(lpfnGetProcessID));
}
};
template <typename T>
std::function<T> loadDllFunc(const std::string& dllName, const std::string& funcName) {
// Load DLL.
HINSTANCE hGetProcIDDLL = LoadLibrary(dllName.c_str());
// Check if DLL is loaded.
if (hGetProcIDDLL == NULL) {
std::cerr << "Could not load DLL \"" << dllName << "\"" << std::endl;
exit(EXIT_FAILURE);
}
// Locate function in DLL.
FARPROC lpfnGetProcessID = GetProcAddress(hGetProcIDDLL, funcName.c_str());
// Check if function was located.
if (!lpfnGetProcessID) {
std::cerr << "Could not locate the function \"" << funcName << "\" in DLL\"" << dllName << "\"" << std::endl;
exit(EXIT_FAILURE);
}
// Create function object from function pointer.
return TypeParser<T>::createFunction(lpfnGetProcessID);
}

Related

How to portably load dynamic libraries and run their initialization code?

Using GCC and being on Linux, or probably wherever glibc is available, I can use the dl_open() library function to dynamically load a shared-object/DLL:
void *dlopen(const char *filename, int flags);
... and this also runs all functions which, in the ELF format, are marked with .init; or in the C/C++ code, are marked with __attribute__((constructor)) :
How exactly does __attribute__((constructor)) work?
My question is: How can I do the same in a more portable way? I'm interested in portability both to other compilers and other platforms.
Note: I marked this C++ because that's what I'm using, but obviously a C-ish solution in acceptable - as what I've described above is a C-ish solution.
Initializing when library loaded
Edit: Revisited the question again and I found that I didn't answer the initialization part.
The best answer I found is this one which is still platform dependent. Will update if there is a better one.
For platform specific
In windows it's DllMain but be sure to read the part of Dynamic link library best practice to see what's unsafe to call in DllMain
In linux:
__attribute__ ((constructor))
__attribute__ ((destructor))
Load library portably
Since Boost is available on many platforms, its _dll module might be considered as cross platform. Though compilation for different platforms are required.
Following is the basic example for Boost.Dll by importing a single variable in plugin.
Header
#include <boost/config.hpp>
#include <string>
class BOOST_SYMBOL_VISIBLE my_plugin_api {
public:
virtual std::string name() const = 0;
virtual float calculate(float x, float y) = 0;
virtual ~my_plugin_api() {}
};
Source
#include <boost/config.hpp> // for BOOST_SYMBOL_EXPORT
#include "../tutorial_common/my_plugin_api.hpp"
namespace my_namespace {
class my_plugin_sum : public my_plugin_api {
public:
my_plugin_sum() {
std::cout << "Constructing my_plugin_sum" << std::endl;
}
std::string name() const {
return "sum";
}
float calculate(float x, float y) {
return x + y;
}
~my_plugin_sum() {
std::cout << "Destructing my_plugin_sum ;o)" << std::endl;
}
};
// Exporting `my_namespace::plugin` variable with alias name `plugin`
// (Has the same effect as `BOOST_DLL_ALIAS(my_namespace::plugin, plugin)`)
extern "C" BOOST_SYMBOL_EXPORT my_plugin_sum plugin;
my_plugin_sum plugin;
} // namespace my_namespace
Usage: note that append_decorations is the way for seeking platform specific naming convention.
Eg: libplugin.so on linux or plugin.dll on windows.
#include <boost/dll/import.hpp> // for import_alias
#include <iostream>
#include "../tutorial_common/my_plugin_api.hpp"
namespace dll = boost::dll;
int main(int argc, char* argv[]) {
boost::dll::fs::path lib_path(argv[1]); // argv[1] contains path to directory with our plugin library
boost::shared_ptr<my_plugin_api> plugin; // variable to hold a pointer to plugin variable
std::cout << "Loading the plugin" << std::endl;
plugin = dll::import<my_plugin_api>( // type of imported symbol is located between `<` and `>`
lib_path / "my_plugin_sum", // path to the library and library name
"plugin", // name of the symbol to import
dll::load_mode::append_decorations // makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`
);
std::cout << "plugin->calculate(1.5, 1.5) call: " << plugin->calculate(1.5, 1.5) << std::endl;
}
To create an object from plugin, here's the factory example.
First, make a factory method returns boost::shared_ptr<my_plugin_aggregator>.
#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
#include "../tutorial_common/my_plugin_api.hpp"
namespace my_namespace {
class my_plugin_aggregator : public my_plugin_api {
float aggr_;
my_plugin_aggregator() : aggr_(0) {}
public:
std::string name() const {
return "aggregator";
}
float calculate(float x, float y) {
aggr_ += x + y;
return aggr_;
}
// Factory method
static boost::shared_ptr<my_plugin_aggregator> create() {
return boost::shared_ptr<my_plugin_aggregator>(
new my_plugin_aggregator()
);
}
};
BOOST_DLL_ALIAS(
my_namespace::my_plugin_aggregator::create, // <-- this function is exported with...
create_plugin // <-- ...this alias name
)
} // namespace my_namespace
Load creator method and create object.
#include <boost/dll/import.hpp> // for import_alias
#include <boost/function.hpp>
#include <iostream>
#include "../tutorial_common/my_plugin_api.hpp"
namespace dll = boost::dll;
int main(int argc, char* argv[]) {
boost::dll::fs::path shared_library_path(argv[1]); // argv[1] contains path to directory with our plugin library
shared_library_path /= "my_plugin_aggregator";
typedef boost::shared_ptr<my_plugin_api> (pluginapi_create_t)();
boost::function<pluginapi_create_t> creator;
creator = boost::dll::import_alias<pluginapi_create_t>( // type of imported symbol must be explicitly specified
shared_library_path, // path to library
"create_plugin", // symbol to import
dll::load_mode::append_decorations // do append extensions and prefixes
);
boost::shared_ptr<my_plugin_api> plugin = creator();
std::cout << "plugin->calculate(1.5, 1.5) call: " << plugin->calculate(1.5, 1.5) << std::endl;
std::cout << "plugin->calculate(1.5, 1.5) second call: " << plugin->calculate(1.5, 1.5) << std::endl;
std::cout << "Plugin Name: " << plugin->name() << std::endl;
}
Note: When creator is destroyed, dynamic library is unloaded as well. Dereferencing plugin after library unloaded is undefined behavior.

How to pass caller function name to callee function using default parameters

Consider the below code :
#include <iostream>
void test_function(const char* caller_name = __FUNCTION__) {
std::cout << caller_name << " ";
}
void func1() {
test_function();
}
int main() {
test_function();
func1();
}
The above code prints nothing.
Is there any way that test_function prints the name of the function from which it is called ?
Eg : For this case, output should be : main func1
I understand that desired output can be achieved if we make the argument to test_function, non default, and pass __FUNCTION__ from the caller function.
This could be achieved by using macro also, but it is not what I am looking for.
Use a macro
#define TEST_FUNCTION() test_function(__FUNCTION__)
void test_function(const char *caller) {
std::cout << caller << '\n';
}
void foo() {
TEST_FUNCTION(); // prints foo
}
int main() {
TEST_FUNCTION(); // prints main
foo();
}

Is there a way to get a signature based typeinfo mangled function name using RTTI?

I want to use RTTI and mangled function (pointer) type strings.
Before you categorize this as an XY problem, I'm aware that there are better options to bind functions using polymorphism etc.
This is a purely academical question how to use typeid() properly with function pointers that should differ by their legally overloaded signatures.
If I use the following code, it seems I can retrieve unique typeinfo::name() values for various namespaces/types:
#include <iostream>
#include <typeinfo>
#include <string>
void foo(int) {
}
namespace woozle {
void goozle(int) {}
}
struct bar {
void baz(int) {}
static void boo(int) {}
};
int main() {
std::cout << typeid(&foo).name() << std::endl;
std::cout << typeid(&woozle::goozle).name() << std::endl;
std::cout << typeid(&bar::baz).name() << std::endl;
std::cout << typeid(&bar::boo).name() << std::endl;
}
The output is:
PFviE
PFviE
M3barFviE
PFviE
Perfectly what I expected (I assume the i in the mangled name refers to the parameter signature).
Now I want to have something like this (which is perfectly legal function overloading):
#include <iostream>
#include <typeinfo>
#include <string>
void foo(int) {
}
void foo(std::string) {
}
namespace woozle {
void goozle(int) {}
void goozle(std::string) {}
}
struct bar {
void baz(int) {}
static void boo(int) {}
void baz(std::string) {}
static void boo(std::string) {}
};
int main() {
std::cout << typeid(&foo).name() << std::endl;
std::cout << typeid(&woozle::goozle).name() << std::endl;
std::cout << typeid(&bar::baz).name() << std::endl;
std::cout << typeid(&bar::boo).name() << std::endl;
}
and of course the compiler complains about ambiguity:
main.cpp: In function 'int main()':
main.cpp:24:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&foo).name() << std::endl;
^~~~
main.cpp:25:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&woozle::goozle).name() << std::endl;
^~~~~~~
main.cpp:26:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&bar::baz).name() << std::endl;
^~~~
main.cpp:27:25: error: address of overloaded function with no contextual type information
std::cout << typeid(&bar::boo).name() << std::endl;
^~~~
TL;DR
What is the proper syntax to specify a specific function overload with typeid() (if there is any)?
How can I provide the "contextual type information" that is demanded from the error message?
I'm coming from here in deep thinking mode.
To select a specific function from a set of overloaded functions you can use use the cast notation:
std::cout << typeid(static_cast<void (*)(int)>(foo)).name() << std::endl;
std::cout << typeid(static_cast<void (*)(std::string)>(foo)).name() << std::endl;
std::cout << typeid(static_cast<void (bar::*)(int)>(&bar::baz)).name() << std::endl;
std::cout << typeid(static_cast<void (bar::*)(std::string)>(&bar::baz)).name() << std::endl;
Specifically with typeid though, if you have the type already written down, you can skip the actual function name.
std::cout << typeid(void (*)(int)).name() << std::endl;
is shorter and does the job just as well.

Copying 'this' pointer

Got very weird problem...
I have variable:
Application *ApplicationHandle = NULL;
in Application's function I do:
ApplicationHandle = this;
And ApplicationHandle still remains as NULL... i'm checking this with debugger, before this operation ApplicationHandle is NULL, and 'this' got some address, I can see variables of this class that are valid. After operation ApplicationHandle should be the same pointer as this, but it is still NULL.
How is that possible?
I would suggest moving the static variable out of the global namespace and into the class as a static class member. Here is an example:
// test.hpp
#ifndef TEST_HPP
#define TEST_HPP
class Test
{
public:
// Constructor: Assign this to TestPointer
Test(void) { TestPointer = this; }
// This is just a definition
static Test* TestPointer;
private:
unsigned m_unNormalMemberVariable;
};
#endif /* #ifndef TEST_HPP */
The above code will not work by itself, you need to declare the actual memory of the static member variable (just like you would for a member function).
// test.cpp
#include "test.hpp"
#include <iostream>
// The actual pointer is declared here
Test* Test::TestPointer = NULL;
int main(int argc, char** argv)
{
Test myTest;
std::cout << "Created Test Instance" << std::endl;
std::cout << "myTest Pointer: " << &myTest << std::endl;
std::cout << "Static Member: " << Test::TestPointer << std::endl;
Test myTest2;
std::cout << "Created Second Test Instance" << std::endl;
std::cout << "myTest2 Pointer: " << &myTest2 << std::endl;
std::cout << "Static Member: " << Test::TestPointer << std::endl;
return 0;
}
The static member can be access from any file, not just the file containing the line Test* Test::TestPointer = NULL;. To access the contents of the static pointer, use Test::TestPointer.

C++ Simple Reflection without Macros: Print Variable Name and Its Value

Is there a non-macro way in C++ of printing a variable name with its value. Here is the macro way:
#define SHOW(a) std::cout << #a << ": " << (a) << std::endl
PS: I'm using Linux and do not need a cross-platform solution
No, C++ does not support reflection and the only way of doing this (as far as I know) are with macros.
You can use dynamic symbols, but then it will only work in shared libraries or executables compiled with the -rdynamic flag. And it will recognize just global variables with default dynamic visibility.
#include <dlfcn.h>
#include <iostream>
int NameMe = 42;
const char *GetName(const void *ptr)
{
Dl_info info;
if (dladdr(ptr, &info))
return info.dli_sname;
else
return NULL;
}
template<typename T>
void Dump(const T &t)
{
const char *name = GetName(&t);
if (name)
std::cout << name;
else
std::cout << "<unknown>";
std::cout << ": " << t << std::endl;
}
int main()
{
int NoName = 33;
Dump(NameMe);
Dump(NoName);
return 0;
}
$ g++ dump.cpp -ldl -rdynamic
$ ./a.out
NameMe: 42
<unknown>: 33
No way.
Without macro, you've to do this:
std::cout <<"a : " << a << std::endl;
No other way.
If you can have all your classes derive from a common ancestor, you can provide a virtual function that accomplishes this. I haven't tried this template, it might not work - some feedback would be appreciated.
struct Reflector
{
virtual void Show() = 0;
};
template<class a, char name[]>
struct ReflectorImpl : public Reflector
{
virtual void Show()
{
std::cout << name << ": " << *this << std::endl;
}
};
class MyClass: public ReflectorImpl<MyClass, "MyClass">
{
};
Yes; in C++17 you can use PFR (in C++17 mode) to get nontrivial levels of non-macro reflection. There are related mechanisms for reflecting the "string-value" of an enum.
See https://github.com/apolukhin/magic_get ;
And https://github.com/Neargye/magic_enum .