954,496 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Boost Threads with CLR dll --- exe works fine

I am using Visual C++ 2010 and created a CLR EXE debug project and wrote a function, which I am able to call from main in my program. If I take the exact same code and put it in a dll, then I get a compile error
from the line

m_thread=boost::shared_ptr( new boost::thread( boost::bind( &MyClass::Work, this ) ) );

The error message is

error LNK2022: metadata operation failed (8013119F) : A TypeRef exists which should, but does not, have a corresponding TypeDef: (dummy): (0x01000022).

I have no idea what the problem is since this works perfectly in the EXE project and the dll works fine if I use .NET managed threads instead.

twc2102
Newbie Poster
4 posts since Jun 2010
Reputation Points: 10
Solved Threads: 0
 

I would like to have a look at this. If you have a mini project which reproduces the error that would save me a lot of time. Thanks

AkashL
Light Poster
29 posts since Jun 2010
Reputation Points: 10
Solved Threads: 4
 

The boost::thread class forward declares a struct called dummy. Long story short, you can work around it by adding a definition in one of the.cpp files for your project.

namespace boost {
    struct thread::dummy {};
}

For AkashL, just create a console CLR project and throw in a simple thread to reproduce the error.

// test.cpp : main project file.

#include "stdafx.h"

using namespace System;

#include <boost/thread/thread.hpp>

void run() {}

int main(array<System::String ^> ^args)
{
    boost::thread t(run);
}

And the fix is as Edward says.

// test.cpp : main project file.

#include "stdafx.h"

using namespace System;

#include <boost/thread/thread.hpp>

namespace boost {
    struct thread::dummy {};
}

void run() {}

int main(array<System::String ^> ^args)
{
    boost::thread t(run);
}
Radical Edward
Posting Pro
545 posts since May 2008
Reputation Points: 361
Solved Threads: 97
 

When I use your code in an EXE, I get warning LNK4248: unresolved typeref token (0100001F) for 'boost.detail.win32._SECURITY_ATTRIBUTES'; image may not run

There is an immediate error at startup: The application failed to initialize properly (0xc000007b).

The run-time error remains, but the warning disappears if I add the code

namespace boost { namespace detail { namespace win32 {
struct _SECURITY_ATTRIBUTES {};
};};};

If I replace the #include line with the four lines below, the exe will work

#pragma managed(push, off)
extern "C" void tss_cleanup_implemented(void) {}
#include
#pragma managed(pop)

If I turn main into an exported function in a dll, I have been unable to call the function successfully in an exe that references the dll. I either get an error about multiple definitions for tss_cleanup_implemented or if I compile without that line, the exe crashed at startup.

twc2102
Newbie Poster
4 posts since Jun 2010
Reputation Points: 10
Solved Threads: 0
 

Also if use the preprocessor definition

#if defined(_MANAGED)
#define BOOST_USE_WINDOWS_H
#endif

Then I get the error messages

1>c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(96): error C2872: 'IServiceProvider' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(53) : System::IServiceProvider IServiceProvider'
1> or 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\mscorlib.dll : System::IServiceProvider'
1>c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(96): error C3699: '*' : cannot use this indirection on type 'IServiceProvider'
1> compiler replacing '*' with '^' to continue parsing
1>c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(103): error C2371: 'IServiceProvider' : redefinition; different basic types
1> c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(53) : see declaration of 'IServiceProvider'
1>c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(120): error C2872: 'IServiceProvider' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(103) : IServiceProvider'
1> or 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\mscorlib.dll : System::IServiceProvider'
1>c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(241): error C2872: 'IServiceProvider' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(103) : IServiceProvider'
1> or 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\mscorlib.dll : System::IServiceProvider'
1>c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(251): error C2872: 'IServiceProvider' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(103) : IServiceProvider'
1> or 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\mscorlib.dll : System::IServiceProvider'
1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\urlmon.h(6459): error C2872: 'IServiceProvider' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(103) : IServiceProvider'
1> or 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\mscorlib.dll : System::IServiceProvider'
1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\urlmon.h(6461): error C2872: 'IServiceProvider' : ambiguous symbol
1> could be 'c:\program files\microsoft sdks\windows\v7.0a\include\servprov.h(103) : IServiceProvider'
1> or 'c:\program files\reference assemblies\microsoft\framework\.netframework\v4.0\mscorlib.dll : System::IServiceProvider'

twc2102
Newbie Poster
4 posts since Jun 2010
Reputation Points: 10
Solved Threads: 0
 

Source code for a simple example is below

//CLR_DLL.def
LIBRARY CLR_DLL
EXPORTS
CLR_TEST

//CLR_DLL.h
#ifndef CLR_DLL_H
#define CLR_DLL_H
//define CLR_DLL in the CLR_DLL project, but not the executable
#ifndef CLR_DLL
#pragma comment(lib, "CLR.lib")
#pragma message("Using Library CLR.lib")
#endif
void _stdcall CLR_TEST();
#endif

//CLR_DLL.cpp
#ifndef CLR_DLL_H
#include
#endif
//include directory C:\Program Files\boost\boost_1_43_0
//lib directory C:\Program Files\boost\boost_1_43_0\stage\lib
#pragma managed(push, off)
//dll will not compile without next line, but executable would crash without it!
//extern "C" void tss_cleanup_implemented(void) {}
#include
#pragma managed(pop)

#pragma unmanaged
namespace boost {
struct thread::dummy {};
}

namespace boost {
namespace detail {
namespace win32 {
struct _SECURITY_ATTRIBUTES {};
};
};
};


void run() {}

void test() {
boost::thread t(run);
}

void _stdcall CLR_TEST() {
test();
}

//MAIN.cpp in exe project
#include
int main(array ^args) {
CLR_TEST();
return 0;
}

twc2102
Newbie Poster
4 posts since Jun 2010
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: