Take a look at my cppcomponents projects at https://github.com/jbandela/cppcomponents . I created this library specifically for scenarios like yours, as I found solutions currently available.
This is a C ++ 11 library designed for headers only, which runs on Windows and Linux.
This requires a fairly compatible C ++ 11 compiler, such as MSVC 2013, Gcc 4.7.2, or Clang 3.2
- It automatically processes the implementation of QueryInterface, AddRef, and Release.
- When you use it, reference counting is processed automatically
- It allows you to return std :: string, vector, tuple, as well as other standard types
- It can handle exceptions
- You can use several compilers, for example, you can write your program in Visual C ++ and write your plugins in GCC
Here is the easiest way to write what you want
First define the interface and plugin in CommandProvider.h
#include <cppcomponents/cppcomponents.hpp> #include <tuple> #include <vector> typedef std::tuple<int, std::wstring, std::wstring> Command; struct ICommandProvider:cppcomponents::define_interface<cppcomponents::uuid<0xf4b4056d, 0x37a8, 0x4f32, 0x9eea, 0x03a31ed55dfa>> { std::vector<Command>GetEmergeInternalCommands(); CPPCOMPONENTS_CONSTRUCT(ICommandProvider, GetEmergeInternalCommands) }; inline std::string CommandProviderId(){ return "CommandProvider"; } typedef cppcomponents::runtime_class<CommandProviderId, cppcomponents::object_interfaces<ICommandProvider>> CommandProvider_t; typedef cppcomponents::use_runtime_class<CommandProvider_t> CommandProvider;
Then in ImplementCommandProvider.cpp to be compiled into CommandProviderDll.dll
#include "CommandProvider.h" struct ImplementCommandProvider :cppcomponents::implement_runtime_class<ImplementCommandProvider, CommandProvider_t> { ImplementCommandProvider(){} std::vector<Command>GetEmergeInternalCommands(){ std::vector<Command> vec; vec.push_back(std::make_tuple(1, L"Test", L"TestFunction")); vec.push_back(std::make_tuple(2, L"Test2", L"TestFunction2")); vec.push_back(std::make_tuple(3, L"Test3", L"TestFunction3")); return vec; } }; CPPCOMPONENTS_REGISTER(ImplementCommandProvider) CPPCOMPONENTS_DEFINE_FACTORY()
This is how you use it
#include "CommandProvider.h" #include <iostream> int main(){ std::string dllName; std::cout << "Enter dll name without the .dll extension\n"; std::cin >> dllName; auto p = CommandProvider::dynamic_creator(dllName, "CommandProvider")(); for (auto& c : p.GetEmergeInternalCommands()){ std::wcout << L"Value " << std::get<0>(c) << L" Name " << std::get<1>(c) << L" Function " << std::get<2>(c) << L"\n"; } }
Here is how you could build it from the command line. I assume that you are in a directory with 3 files and that the MSVC compiler is on your way.
Here's how to create a core program.
cl MainProgram.cpp /I c:\Users\jrb\Source\Repos\cppcomponents /EHsc
Here's How to Build a Dll
cl ImplementCommandProvider.cpp /I c:\Users\jrb\Source\Repos\cppcomponents /EHsc /link /dll /OUT:CommandProviderDll.dll
Then, when you run the program, enter CommandProviderDll for your dllname
If you want to define a custom structure, this is possible, and I can help you with it.
The library currently does not have documentation (working on it :(), but I can help you with any questions you have about the library. The library is released under the Boost license, so you can use it for commercial applications if you want.