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<boost::thread>( 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.
--------------
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);
}
-----------------------------
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 <boost/thread/thread.hpp>
#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.
---------------------------
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
----------------------------------------
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 <CLR_DLL.h>
#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 <boost/thread/thread.hpp>
#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 <CLR.h>
int main(array<System:tring ^> ^args) {
CLR_TEST();
return 0;
}