Greetings. This is my first use of Boost, despite knowing of its existence for quite some time.

 

I’ve compiled Boost 1.41 with msvc and am using basically the tutorial code for program_options. When I compile it as native c++ with the msvc compiler, it works fine, however when I wrap the same code into a c++ dll to be called via .NET C# code, the variables_map always fails to locate the program options via .count(“option_name”).

 

I’ve stepped through the debugger and that doesn’t really help because the debugger is unable to list the contents of variables that are outside of the current stack frame (according to Microsoft), even though when I try to access the contents of the variables the stack pointer is in their respective single-threaded assemblies.

 

I’m hoping someone here has experience integrating Boost with .net via a c++/clr dll and can help point me to what the problem might be. Somewhere in the parse_command_line() call is where I lose track of the variable data. Before the call to po::store(po::parse_command_line(argc, cstr, desc), vm); the argc, argv, and desc variables contain the correct contents. The result of the below code is that “Compression level was not set.” is always output.

 

The non-working dll code:

 

// mtest1.cpp : Defines the exported functions for the DLL application.

//

 

#include "stdafx.h"

#include <tchar.h>

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

#include <windows.h>

#include <iostream>

#include <msclr/marshal.h>

#include <boost/program_options.hpp>

#using<mscorlib.dll>

 

using namespace System;

using namespace std;

using namespace msclr::interop;

namespace po = boost::program_options;

 

namespace boost_TestDLL

{

       public ref class Boost_Test

       {

       public:

              static void Test(int argc, array<String^>^ argv)

              {

                     //convert String array to char* array

                     marshal_context ^ context = gcnew marshal_context();

                     char** cstr = new char*[argc];

                     for(int i = 0; i < argc; i++) {

                           cstr[i] = (char*)context->marshal_as<const char*>(argv[i]);

                     }

 

                     po::options_description desc("Allowed options");

                     desc.add_options()

                         ("help", "produce help message")

                         ("compression", po::value<int>(), "set compression level")

                     ;

 

                     po::variables_map vm;

                     po::store(po::parse_command_line(argc, cstr, desc), vm);

                     po::notify(vm);

 

                     if (vm.count("help")) {

                         cout << desc << "\n";

                     } else if (vm.count("compression")) {

                         cout << "Compression level was set to " << vm["compression"].as<int>() << ".\n";

                     } else {

                         cout << "Compression level was not set.\n";

                     }

                    

                     delete context;

              }

       };

}