CLR and boost ...

Started by
8 comments, last by stonemetal 16 years, 2 months ago
Hi, I'm having trouble using boost in a project compiled with CLR support ... It throws an exception before the main entrypoint is even reached ... When debugging, the debugger puts me in regex.cpp, and in the call stack, I'm just after [Managed to Native Transition] ... don't know if that might help. Well, the part of my program which uses boost is a static library which is included in a WinForm project. I tried to add #pragma managed(push, off) wherever I used boost, but it didn't work. Anyone has an idea ? Thx in advance.
Advertisement
You might start by telling what the exception is and what the program does in the non-managed library. Maybe you can prepare a simple test program to quote in full.

Omae Wa Mou Shindeiru

You're right. Just thought it might be a problem someone already had :)
Well, I can't create a simple program right now, so I'll try to explain a bit more.

I have a solution with 2 projects. One is a static library with common language runtime support enabled. It also uses boost::regex.
The other is a WinForm application which uses the static library generated by the first project.

It doesn't generate any errors during compiling / linking, even with /W4. But when I launch the WinForm, it crashes before even entering the main entrypoint. The exception is something like :

Debug Assertion Failed!
Program: ...
Expression: _CrtIsValidHeapPointer(pUserData)

And when I hit "Retry" to debug, it points me to regex.cpp, line 191 ...
In the call stack, the highlighed line is
"EXENAME.exe!boost::re_detail:: `dynamic initializer for 'block_cache''()"
just after a line :
"[Managed to Native Transition]"

The strange thing is when I disable the CLR support, the program still crashes, but at the initialization of a static member variable of one of my classes.

And also : all these things worked fine before I started using boost (the static member variable was correctly initialized, I had no exceptions, etc.)

Hope I was a little more detailed :)
Easy fix, don't use boost with managed code. .net has regexes built in why not use them since you are already using manged code.
Because I'm using them in the static library which doesn't use .NET ... I said that I could compile it without CLR support.

And that wouldn't be a fix. A workaround at best, but not a fix :)


Anyway, I've created a little project, which worked fine ... until I started to play with project options ! And I reproduced the problem.

First, create a Solution with 2 empty project. One is a CLR project, executable, the other is a static library with CLR support.

In the static lib project, add 2 files : Foo.h and Foo.cpp with the following code :
// file : Foo.h#pragma onceclass Foo{public:    Foo(void);    ~Foo(void);    bool DoSomething(void);};


// file : Foo.cpp#include "Foo.h"#include <boost/regex.hpp>#include <string>Foo::Foo(void){}Foo::~Foo(void){}bool Foo::DoSomething(void){    boost::regex e("foo");    boost::match_results< std::string::const_iterator > matches;    if (boost::regex_match(std::string("bar"), matches, e))        return(true);    return(false);}


In the executable project, create a test.cpp file and add this code :
#include "../StaticLib/Foo.h"using namespace System;[STAThreadAttribute]int main(array<System::String ^> ^args){    Foo * foo = new Foo();    if (foo->DoSomething()) Console::WriteLine("match !");    else                    Console::WriteLine("doesn't match :(");    delete foo;    return 0;}


Now, in the executable project, add the input library, and ensure that Configuration Properties > Linker > Advanced > Entry Point is set to main and Configuration Properties > Linker > System > SubSystem is set to Windows (/SUBSYSTEM:WINDOWS)

Run and you have an exception.


In my initial project, I just didn't set Subsystem and Entry Point and now it works.

Now my problem is that I have a console window. But at least I can move one.

My feeling is that it has something to do with global / static variables initializations ... but I'm not good enough to understand what really happens, and eventually correct to problem.

So if anyone can explain to me what happens ... :)
Thx !
I didn't have time to fully read all the replies - but I recall having similar issues when trying to develop a cli/.net extension to my existing code (which used boost smart pointers)..

If I remember correctly, the problem was that both libraries were trying to manage my pointers... so things were being "gc'd" twice.

What I did at the time was create a .net wrapper around boost smart pointers.

Sorry I cannot recall more depth.. I know on my next project, I analysed whether I wanted to carry on learning boost or .net, since I found the work to be a waste of time. I ended up continuing with boost.
sounds kind of like this problem we had at work try:

Change the entry point of the application to ?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z


https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101712
http://www.thescripts.com/forum/thread642179.html
Hmm.. Boost.Regex is one of the Boost libraries which contains actual object files, rather than simply consisting of headers. Including the regex header magically informs the linker to link the appropriate boost library. It's possible that some way in which this library is chosen doesn't play well with the CLR. Try defining BOOST_REGEX_NO_LIB before you include the regex header. Then make sure to link with the appropriate Boost.Regex LIB file.
Quote:Original post by stonemetal
sounds kind of like this problem we had at work try:

Change the entry point of the application to ?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z


https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101712
http://www.thescripts.com/forum/thread642179.html


0_0 A real wizard !! Harry Potter, go hide yourself, you've found your master !! :)

That works. I'm going to read the posts you linked, because this simply looks taht random magic to me, and I'd really like to understand that :p

Thx anyway !
To boil it down, .net doesn't allow native static initialization to work properly. the change of the entry point makes it run the native code's static initialization correctly. The odd name is how visual studio mangles names.

This topic is closed to new replies.

Advertisement