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.

Recommended Answers

All 5 Replies

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

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
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'

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;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.