Sign in to follow this  
paic

CLR and boost ...

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
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 once

class 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 !

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 !

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this