Your main problem is that passing C++ types across DLL boundaries is difficult.
You need the following
- Same compiler
- Same standard library
- Same settings for exceptions
- In Visual C++ you need same version of the compiler
- In Visual C++ you need same Debug/Release configuration
- In Visual C++ you need same Iterator debug level
And so on
If that is what you want, I wrote a header-only library called cppcomponents https://github.com/jbandela/cppcomponents that provides the easiest way to do it in C++.
You need a compiler with strong support for C++11. Gcc 4.7.2 or 4.8 will work. Visual C++ 2013 preview also works.
I will walk you through using cppcomponents to solve your problem.
-
git clone https://github.com/jbandela/cppcomponents.git
in the directory of your choice. We will refer to the directory where you ran this command aslocalgit
-
Create a file called
interfaces.hpp
. In this file you will define the interface that can be used across compilers.
Enter the following
#include <cppcomponents/cppcomponents.hpp>
using cppcomponents::define_interface;
using cppcomponents::use;
using cppcomponents::runtime_class;
using cppcomponents::use_runtime_class;
using cppcomponents::implement_runtime_class;
using cppcomponents::uuid;
using cppcomponents::object_interfaces;
struct IGetFiles:define_interface<uuid<0x633abf15,0x131e,0x4da8,0x933f,0xc13fbd0416cd>>{
std::vector<std::string> GetFiles();
CPPCOMPONENTS_CONSTRUCT(IGetFiles,GetFiles);
};
inline std::string FilesId(){return "Files!Files";}
typedef runtime_class<FilesId,object_interfaces<IGetFiles>> Files_t;
typedef use_runtime_class<Files_t> Files;
Next create an implementation. To do this create Files.cpp
.
Add the following code
#include "interfaces.h"
struct ImplementFiles:implement_runtime_class<ImplementFiles,Files_t>{
std::vector<std::string> GetFiles(){
std::vector<std::string> ret = {"samplefile1.h", "samplefile2.cpp"};
return ret;
}
ImplementFiles(){}
};
CPPCOMPONENTS_DEFINE_FACTORY();
Finally here is the file to use the above. Create UseFiles.cpp
Add the following code
#include "interfaces.h"
#include <iostream>
int main(){
Files f;
auto vec_files = f.GetFiles();
for(auto& name:vec_files){
std::cout << name << "\n";
}
}
Now you can compile. Just to show we are compatible across compilers, we will use cl
the Visual C++ compiler to compile UseFiles.cpp
into UseFiles.exe
. We will use Mingw Gcc to compile Files.cpp
into Files.dll
cl /EHsc UseFiles.cpp /I localgit\cppcomponents
where localgit
is the directory in which you ran git clone
as described above
g++ -std=c++11 -shared -o Files.dll Files.cpp -I localgit\cppcomponents
There is no link step. Just make sure Files.dll
and UseFiles.exe
are in the same directory.
Now run the executable with UseFiles
cppcomponents will also work on Linux. The main change is when you compile the exe, you need to add -ldl
to the flag, and when you compile the .so file, you need to add -fPIC
to the flags.
If you have further questions, let me know.