Passing reference to STL vector over dll boundary

Your main problem is that passing C++ types across DLL boundaries is difficult.
You need the following

  1. Same compiler
  2. Same standard library
  3. Same settings for exceptions
  4. In Visual C++ you need same version of the compiler
  5. In Visual C++ you need same Debug/Release configuration
  6. 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.

  1. 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 as localgit

  2. 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.

Leave a Comment