diff --git a/dc/README.md b/dc/README.md index 2bf28fe09..116d58797 100644 --- a/dc/README.md +++ b/dc/README.md @@ -1 +1,7 @@ ## Dynamic Code + +``` +cd example +clang++ -std=c++1y mysql.cpp -o ../tmp/mysql.so -shared -fPIC +clang++ -std=c++1y test.cpp -o test.out -ldl +``` diff --git a/dc/example/db.hpp b/dc/example/db.hpp new file mode 100644 index 000000000..a507968df --- /dev/null +++ b/dc/example/db.hpp @@ -0,0 +1,19 @@ +#ifndef MEMGRAPH_DL_EXAMPLE_DB_HPP +#define MEMGRAPH_DL_EXAMPLE_DB_HPP + +#include <iostream> + +using namespace std; + +class db +{ +public: + virtual void name() const; + virtual void type() const; + virtual ~db() {} +}; + +typedef db* (*produce_t)(); +typedef void (*destruct_t)(db*); + +#endif diff --git a/dc/example/memsql.cpp b/dc/example/memsql.cpp new file mode 100644 index 000000000..b8fa37ef4 --- /dev/null +++ b/dc/example/memsql.cpp @@ -0,0 +1,28 @@ +#include "db.hpp" + +class memsql : public db +{ +public: + + void name() const override + { + cout << "MemSQL" << endl; + } + + void type() const override + { + cout << "InMemory" << endl; + } + + ~memsql() {} +}; + +extern "C" db* produce() +{ + return new memsql(); +} + +extern "C" void destruct(db* p) +{ + delete p; +} diff --git a/dc/example/mysql.cpp b/dc/example/mysql.cpp new file mode 100644 index 000000000..3b6c1bb2c --- /dev/null +++ b/dc/example/mysql.cpp @@ -0,0 +1,28 @@ +#include "db.hpp" + +class mysql : public db +{ +public: + + virtual void name() const + { + cout << "MySQL" << endl; + } + + virtual void type() const + { + cout << "Relational" << endl; + } + + ~mysql() {} +}; + +extern "C" db* produce() +{ + return new mysql(); +} + +extern "C" void destruct(db* p) +{ + delete p; +} diff --git a/dc/example/neo4j.cpp b/dc/example/neo4j.cpp new file mode 100644 index 000000000..0418bed74 --- /dev/null +++ b/dc/example/neo4j.cpp @@ -0,0 +1,28 @@ +#include "db.hpp" + +class neo4j : public db +{ +public: + + void name() const override + { + cout << "Neo4j" << endl; + } + + void type() const override + { + cout << "Graph" << endl; + } + + ~neo4j() {} +}; + +extern "C" db* produce() +{ + return new neo4j(); +} + +extern "C" void destruct(db* p) +{ + delete p; +} diff --git a/dc/example/postgresql.cpp b/dc/example/postgresql.cpp new file mode 100644 index 000000000..34b5445fe --- /dev/null +++ b/dc/example/postgresql.cpp @@ -0,0 +1,28 @@ +#include "db.hpp" + +class postgresql : public db +{ +public: + + void name() const override + { + cout << "PostgreSQL" << endl; + } + + void type() const override + { + cout << "Relational" << endl; + } + + ~postgresql() {} +}; + +extern "C" db* produce() +{ + return new postgresql(); +} + +extern "C" void destruct(db* p) +{ + delete p; +} diff --git a/dc/test.cpp b/dc/test.cpp index 685aa8cde..ba582ad92 100644 --- a/dc/test.cpp +++ b/dc/test.cpp @@ -4,6 +4,8 @@ #include <vector> #include <iterator> #include <cstdlib> +#include <dlfcn.h> +#include "example/db.hpp" // TODO: clang++ file.cpp -o file.so -shared -fPIC @@ -32,15 +34,51 @@ std::string prints(const Args&... args) return join(strings, " "); } +db* database(const std::string& lib_path, const std::string& factory_method) +{ + // load lib + void* db_lib = dlopen(lib_path.c_str(), RTLD_LAZY); + if (!db_lib) { + cerr << "Cannot load library: " << dlerror() << '\n'; + return nullptr; + } + dlerror(); + + // load produce method + produce_t produce_db = (produce_t) dlsym(db_lib, factory_method.c_str()); + const char* dlsym_error = dlerror(); + if (dlsym_error) { + cerr << "Cannot load symbol create: " << dlsym_error << '\n'; + return nullptr; + } + + // load destroy method + // destruct_t destruct_db = (destruct_t) dlsym(db_lib, "destruct"); + // dlsym_error = dlerror(); + // if (dlsym_error) { + // cerr << "Cannot load symbol destroy: " << dlsym_error << '\n'; + // return nullptr; + // } + + db *instance = produce_db(); + + return instance; +} + int main() { - string tmp_file_path = "tmp/tmp.cpp"; - string tmp_so_path = "tmp/tmp.so"; - string for_compile = "#include <iostream>\nint main() { std::cout << \"test\" << std::endl; return 0; }"; + // string tmp_file_path = "tmp/tmp.cpp"; + // string tmp_so_path = "tmp/tmp.so"; + // string for_compile = "#include <iostream>\nint main() { std::cout << \"test\" << std::endl; return 0; }"; - write(tmp_file_path, for_compile); - string test_command = prints("clang++", tmp_file_path, "-o", "test.out"); - system(test_command.c_str()); + // write(tmp_file_path, for_compile); + // string test_command = prints("clang++", tmp_file_path, "-o", "test.out"); + // system(test_command.c_str()); + + db *mysql = database("./tmp/mysql.so", "produce"); + if (mysql) { + mysql->name(); + } return 0; }