Boost Threads with CLR dll --- metadata operation failed

来源:互联网 发布:淘宝网纸箱 编辑:程序博客网 时间:2024/05/23 05:08

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.

  1. namespace boost {
  2. struct thread::dummy {};
  3. }

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

  1. // test.cpp : main project file.
  2. #include "stdafx.h"
  3. using namespace System;
  4. #include <boost/thread/thread.hpp>
  5. void run() {}
  6. int main(array<System::String ^> ^args)
  7. {
  8. boost::thread t(run);
  9. }

And the fix is as Edward says.

  1. // test.cpp : main project file.
  2. #include "stdafx.h"
  3. using namespace System;
  4. #include <boost/thread/thread.hpp>
  5. namespace boost {
  6. struct thread::dummy {};
  7. }
  8. void run() {}
  9. int main(array<System::String ^> ^args)
  10. {
  11. boost::thread t(run);
  12. }

 

-----------------------------

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

  1. //CLR_DLL.def
  2. LIBRARY CLR_DLL
  3. EXPORTS
  4. CLR_TEST
  5. //CLR_DLL.h
  6. #ifndef CLR_DLL_H
  7. #define CLR_DLL_H
  8. //define CLR_DLL in the CLR_DLL project, but not the executable
  9. #ifndef CLR_DLL
  10. #pragma comment(lib, "CLR.lib")
  11. #pragma message("Using Library CLR.lib")
  12. #endif
  13. void _stdcall CLR_TEST();
  14. #endif
  15. //CLR_DLL.cpp
  16. #ifndef CLR_DLL_H
  17. #include <CLR_DLL.h>
  18. #endif
  19. //include directory C:\Program Files\boost\boost_1_43_0
  20. //lib directory C:\Program Files\boost\boost_1_43_0\stage\lib
  21. #pragma managed(push, off)
  22. //dll will not compile without next line, but executable would crash without it!
  23. //extern "C" void tss_cleanup_implemented(void) {}
  24. #include <boost/thread/thread.hpp>
  25. #pragma managed(pop)
  26. #pragma unmanaged
  27. namespace boost {
  28. struct thread::dummy {};
  29. }
  30. namespace boost {
  31. namespace detail {
  32. namespace win32 {
  33. struct _SECURITY_ATTRIBUTES {};
  34. };
  35. };
  36. };
  37. void run() {}
  38. void test() {
  39. boost::thread t(run);
  40. }
  41. void _stdcall CLR_TEST() {
  42. test();
  43. }
  44. //MAIN.cpp in exe project
  45. #include <CLR.h>
  46. int main(array<System:tring ^> ^args) {
  47. CLR_TEST();
  48. return 0;
  49. }

 

 

 

 

原创粉丝点击