Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Managed C++/CLI
  4. problem with BOOST threads with mixed mode C++/CLI and Visual Studio 2010 [modified]

problem with BOOST threads with mixed mode C++/CLI and Visual Studio 2010 [modified]

Scheduled Pinned Locked Moved Managed C++/CLI
helpc++csharpdotnetvisual-studio
7 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    T2102
    wrote on last edited by
    #1

    I add reference to BOOST thread header and do not even use it yet. Then when I run my application I immediately get the error message "The application failed to initialize properly. Click on OK to terminate the application." I found a possible solution while googling, but am not sure if it is safe. Their is a run-time error at startup depending on the #pragma managed and #pragma unmanaged usage. "Alas, the default compiler settings may lead to trouble: Statically linking to Boost libraries may yield an executable which chokes on startup with a System.BadImageFormatException, even if the compiler and linker run without warning (a bug, IMHO). Explanantion: <cite author="Anthony Williams" date="2009-02-04 15:54:40 GMT"> The problem is that the static boost thread library tries to hook the native win32 PE TLS callbacks in order to ensure that the thread-local data used by boost thread is cleaned up correctly. This is not compatible with a C++/CLI executable. </cite> Solution: In Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions add BOOST_ALL_DYN_LINK in order to force the usage of the DLLs. In addition copy the necessary DLLs to the directory where the executable resides. E.g. copy boost_thread-vc90-mt-gd-1_XX.dll to MyApp/bin/Debug. Enters the next bug of Visual Studio: The C++/CLI compiler deliberately chooses to ignore the #pragma managed(push, off) / #pragma managed(pop) PREPRO directives for files which are compiled with /clr command line flag. You obtain a plethora of warnings of the form warning C4793: 'boost::[..]::`vcall'{0}'' : function compiled as native : For the executable this means that on termination another exception is thrown, which adds to the confusion: Unhandled exception at 0x7c812a7b in XXX.exe: 0xC0020001: "Die Zeichenfolgenbindung ist unzulässig." or in english: Error 1700 "The string binding is invalid" or RPC_S_INVALID_STRING_BINDING. Solution: Put managed (CLI) and unmanaged C++ code into different compilation units. For unmanaged code files change the compiler settings this way: In "Configuration Properties -> C/C++ -> General -> Compiler with Common Language" support choose "No Common Language Support". "

    modified on Tuesday, June 22, 2010 9:06 AM

    P 1 Reply Last reply
    0
    • T T2102

      I add reference to BOOST thread header and do not even use it yet. Then when I run my application I immediately get the error message "The application failed to initialize properly. Click on OK to terminate the application." I found a possible solution while googling, but am not sure if it is safe. Their is a run-time error at startup depending on the #pragma managed and #pragma unmanaged usage. "Alas, the default compiler settings may lead to trouble: Statically linking to Boost libraries may yield an executable which chokes on startup with a System.BadImageFormatException, even if the compiler and linker run without warning (a bug, IMHO). Explanantion: <cite author="Anthony Williams" date="2009-02-04 15:54:40 GMT"> The problem is that the static boost thread library tries to hook the native win32 PE TLS callbacks in order to ensure that the thread-local data used by boost thread is cleaned up correctly. This is not compatible with a C++/CLI executable. </cite> Solution: In Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions add BOOST_ALL_DYN_LINK in order to force the usage of the DLLs. In addition copy the necessary DLLs to the directory where the executable resides. E.g. copy boost_thread-vc90-mt-gd-1_XX.dll to MyApp/bin/Debug. Enters the next bug of Visual Studio: The C++/CLI compiler deliberately chooses to ignore the #pragma managed(push, off) / #pragma managed(pop) PREPRO directives for files which are compiled with /clr command line flag. You obtain a plethora of warnings of the form warning C4793: 'boost::[..]::`vcall'{0}'' : function compiled as native : For the executable this means that on termination another exception is thrown, which adds to the confusion: Unhandled exception at 0x7c812a7b in XXX.exe: 0xC0020001: "Die Zeichenfolgenbindung ist unzulässig." or in english: Error 1700 "The string binding is invalid" or RPC_S_INVALID_STRING_BINDING. Solution: Put managed (CLI) and unmanaged C++ code into different compilation units. For unmanaged code files change the compiler settings this way: In "Configuration Properties -> C/C++ -> General -> Compiler with Common Language" support choose "No Common Language Support". "

      modified on Tuesday, June 22, 2010 9:06 AM

      P Offline
      P Offline
      Paul Michalik
      wrote on last edited by
      #2

      So what is your question? Yes, mixing boost.thread which uses the native Win32 threading API with CLR code is not without problems. You definitely will need to re-compile boost.threading such that it uses dynamic binding to the multi-threading version of c-runtime libs. Then choose compatible settings when building your C++/CLI project.

      T 1 Reply Last reply
      0
      • P Paul Michalik

        So what is your question? Yes, mixing boost.thread which uses the native Win32 threading API with CLR code is not without problems. You definitely will need to re-compile boost.threading such that it uses dynamic binding to the multi-threading version of c-runtime libs. Then choose compatible settings when building your C++/CLI project.

        T Offline
        T Offline
        T2102
        wrote on last edited by
        #3

        Thanks for the reply. I have written a program that works as a CLR executable with boost threads, but when I make it a DLL I get an immediate crash. I have not been able to figure this out and have posted to the boost community without resolution. 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; }

        P 1 Reply Last reply
        0
        • T T2102

          Thanks for the reply. I have written a program that works as a CLR executable with boost threads, but when I make it a DLL I get an immediate crash. I have not been able to figure this out and have posted to the boost community without resolution. 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; }

          P Offline
          P Offline
          Paul Michalik
          wrote on last edited by
          #4

          Hm, as far as I can tell you need to get the managed/unmanaged #pragmas right and define a conformant dll entry point. But in general, I would not do it that way. Create two distinct projects: 1. a native c++ dll project which uses boost and exports the functionality you need encapsulated in an interface, which has no direct references to boost::thread. Take care to choose multi-threaded and dll version of the runtime libraries. Don't forget to compile boost.threading accordingly!

          // in IMyUnmanagedAPI.h, export/import pragmas ommitted...
          class IMyUnmanagedAPI {
          public:
          virtual DoMyUnmanagedStuff() = 0;
          };

          class MyUnmanagedAPIFactory {
          public:
          static IMyUnmanagedAPI* Create();
          static void Destroy(IMyUnmanagedAPI*);
          };

          2. a c++ dll project with clr support which includes your interface declaration - but nothing else! Make this project use the unmanaged import library generated by project 1. Use a clr wrapper around your unmanaged interface, following the recommended patterns. In your clr project, you only communicate with a pointer to IMyUnmanagedAPI object which (or, better, implementation of which) encapsulates all the boost:: stuff.

          modified on Sunday, August 22, 2010 5:47 AM

          T 1 Reply Last reply
          0
          • P Paul Michalik

            Hm, as far as I can tell you need to get the managed/unmanaged #pragmas right and define a conformant dll entry point. But in general, I would not do it that way. Create two distinct projects: 1. a native c++ dll project which uses boost and exports the functionality you need encapsulated in an interface, which has no direct references to boost::thread. Take care to choose multi-threaded and dll version of the runtime libraries. Don't forget to compile boost.threading accordingly!

            // in IMyUnmanagedAPI.h, export/import pragmas ommitted...
            class IMyUnmanagedAPI {
            public:
            virtual DoMyUnmanagedStuff() = 0;
            };

            class MyUnmanagedAPIFactory {
            public:
            static IMyUnmanagedAPI* Create();
            static void Destroy(IMyUnmanagedAPI*);
            };

            2. a c++ dll project with clr support which includes your interface declaration - but nothing else! Make this project use the unmanaged import library generated by project 1. Use a clr wrapper around your unmanaged interface, following the recommended patterns. In your clr project, you only communicate with a pointer to IMyUnmanagedAPI object which (or, better, implementation of which) encapsulates all the boost:: stuff.

            modified on Sunday, August 22, 2010 5:47 AM

            T Offline
            T Offline
            T2102
            wrote on last edited by
            #5

            Thanks for the suggestion. This week, I am going to take your suggestion of two separate projects, but I will have to have the native C++ dll call the dll with clr support. The reason is that my boost thread code needs to call .NET functionality such as ADO and WebClient.

            P 1 Reply Last reply
            0
            • T T2102

              Thanks for the suggestion. This week, I am going to take your suggestion of two separate projects, but I will have to have the native C++ dll call the dll with clr support. The reason is that my boost thread code needs to call .NET functionality such as ADO and WebClient.

              P Offline
              P Offline
              Paul Michalik
              wrote on last edited by
              #6

              Well, the point is to have the functionality of either worlds compiled separately in distinct translation units. However, the way you seem to be going is a bit harder: You will need to provide abstractions of .NET entities usable in native c++ program. I don't know the background of what you are trying to accomplish, but I would suggest to stay "at one side of the line" (either .NET or native) as long as possible. What you have sketched above (using boost.threading with ADO and Web) smells like problems... There should be a very, very serious reason to do it that way.

              T 1 Reply Last reply
              0
              • P Paul Michalik

                Well, the point is to have the functionality of either worlds compiled separately in distinct translation units. However, the way you seem to be going is a bit harder: You will need to provide abstractions of .NET entities usable in native c++ program. I don't know the background of what you are trying to accomplish, but I would suggest to stay "at one side of the line" (either .NET or native) as long as possible. What you have sketched above (using boost.threading with ADO and Web) smells like problems... There should be a very, very serious reason to do it that way.

                T Offline
                T Offline
                T2102
                wrote on last edited by
                #7

                Thanks for the input. The code works after I separate it into two dlls. The particular function queries multiple webpages on separate threads and webclient was the only CLR functionality I utilized. I then processes the data after all of the threads come back since the processing time is small fraction of the runtime. I also am thinking of building XLL's with functions that retrieve data from the web, require multiple database calls/queries, and do array function computations simultaneously. The .NET threads cannot be utilized in the XLL project, so I have to use Boost threads or some other thread library. The Boost threads cannot be utilized inside the CLR project, but I am not using much more native than .NET code. So I created another dll that makes a native wrapper around the small # of functions I use with CLR.

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups