{"id":11,"date":"2012-05-02T23:25:55","date_gmt":"2012-05-03T04:25:55","guid":{"rendered":"http:\/\/www.brokencode.tumati.net\/?p=11"},"modified":"2012-05-02T23:25:55","modified_gmt":"2012-05-03T04:25:55","slug":"ccli-or-managed-c-and-boostregex-release-build-issues","status":"publish","type":"post","link":"http:\/\/www.brokencode.tumati.net\/?p=11","title":{"rendered":"C++\/CLI (or managed C++) and boost::regex release build issues"},"content":{"rendered":"<p>Sometimes you just don&#8217;t want to bother interfacing with a 3rd-party COM interface doing all the COM-y stuff that&#8217;s required. \u00a0The easiest way is using C++\/CLI and adding a reference to a type library. \u00a0If you happen to have an application that&#8217;s written in C++ and you also happen to use boost::regex, if you do a release build and attempt to build your application with \/clr turned on, you&#8217;re going to end up seeing a problem like this:<\/p>\n<blockquote><p>1&gt;VoidRaySTIIQ.obj : error LNK2001: unresolved external symbol &#8220;void __cdecl boost::re_detail::raise_runtime_error(class std::runtime_error const &amp;)&#8221; (?raise_runtime_error@re_detail@boost@@$$FYAXABVruntime_error@std@@@Z)<br \/>\n1&gt;VoidRaySTIIQ.obj : error LNK2001: unresolved external symbol &#8220;void __cdecl boost::re_detail::put_mem_block(void *)&#8221; (?put_mem_block@re_detail@boost@@$$FYAXPAX@Z)<br \/>\n1&gt;VoidRaySTIIQ.obj : error LNK2001: unresolved external symbol &#8220;void * __cdecl boost::re_detail::get_mem_block(void)&#8221; (?get_mem_block@re_detail@boost@@$$FYAPAXXZ)<br \/>\n1&gt;VoidRaySTIIQ.obj : error LNK2001: unresolved external symbol &#8220;void __cdecl boost::re_detail::verify_options(unsigned int,enum boost::regex_constants::_match_flags)&#8221; (?verify_options@re_detail@boost@@$$FYAXIW4_match_flags@regex_constants@2@@Z)<br \/>\n1&gt;VoidRaySTIIQ.obj : error LNK2001: unresolved external symbol &#8220;class std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt; __cdecl boost::re_detail::w32_transform(unsigned int,char const *,char const *)&#8221; (?w32_transform@re_detail@boost@@$$FYA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IPBD0@Z)<br \/>\n1&gt;VoidRaySTIIQ.obj : error LNK2001: unresolved external symbol &#8220;char const * __cdecl boost::re_detail::get_default_error_string(enum boost::regex_constants::error_type)&#8221; (?get_default_error_string@re_detail@boost@@$$FYAPBDW4error_type@regex_constants@2@@Z)<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<p>Googling for the solution doesn&#8217;t yield an obvious solution, but there is one post that led me to the correct course of action, and that link is here: \u00a0<a href=\"http:\/\/permalink.gmane.org\/gmane.comp.lib.boost.devel\/226293\">http:\/\/permalink.gmane.org\/gmane.comp.lib.boost.devel\/226293<\/a><\/p>\n<p>The issue is that the calling convention is specified incorrectly when you compile a release build. \u00a0For some reason, the library is misconfigured for release operation. \u00a0My hack of a solution (probably not optimal, but it worked&#8230;) was to just rebuild the library after having modified boost\/regex\/config.hpp and replacing the part dealing with calling conventions from this:<\/p>\n<blockquote><p>#if defined(BOOST_MSVC) &amp;&amp; (BOOST_MSVC &gt;= 1200) &amp;&amp; defined(_MSC_EXTENSIONS)<br \/>\n#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED)<br \/>\n# define BOOST_REGEX_CALL __cdecl<br \/>\n#else<br \/>\n# define BOOST_REGEX_CALL __fastcall<br \/>\n#endif<br \/>\n# define BOOST_REGEX_CCALL __cdecl<br \/>\n#endif<\/p>\n<p>#if defined(__BORLANDC__) &amp;&amp; !defined(BOOST_DISABLE_WIN32)<br \/>\n# define BOOST_REGEX_CALL __fastcall<br \/>\n# define BOOST_REGEX_CCALL __stdcall<br \/>\n#endif<\/p>\n<p>#ifndef BOOST_REGEX_CALL<br \/>\n# define BOOST_REGEX_CALL<br \/>\n#endif<br \/>\n#ifndef BOOST_REGEX_CCALL<br \/>\n#define BOOST_REGEX_CCALL<br \/>\n#endif<\/p><\/blockquote>\n<p>to this (where I just make everything a __cdecl to avoid hassles with the preprocessor defines):<\/p>\n<div><\/div>\n<div>\n<blockquote>\n<div>#if defined(BOOST_MSVC) &amp;&amp; (BOOST_MSVC &gt;= 1200) &amp;&amp; defined(_MSC_EXTENSIONS)<\/div>\n<div>#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED)<\/div>\n<div># \u00a0define BOOST_REGEX_CALL __cdecl<\/div>\n<div>#else<\/div>\n<div># \u00a0define BOOST_REGEX_CALL __cdecl<\/div>\n<div>#endif<\/div>\n<div># \u00a0define BOOST_REGEX_CCALL __cdecl<\/div>\n<div>#endif<\/div>\n<div><\/div>\n<div>#if defined(__BORLANDC__) &amp;&amp; !defined(BOOST_DISABLE_WIN32)<\/div>\n<div># \u00a0define BOOST_REGEX_CALL __cdecl<\/div>\n<div># \u00a0define BOOST_REGEX_CCALL __stdcall<\/div>\n<div>#endif<\/div>\n<div><\/div>\n<div>#ifndef BOOST_REGEX_CALL<\/div>\n<div># \u00a0define BOOST_REGEX_CALL __cdecl<\/div>\n<div>#endif<\/div>\n<div>#ifndef BOOST_REGEX_CCALL<\/div>\n<div>#define BOOST_REGEX_CCALL<\/div>\n<div>#endif<\/div>\n<\/blockquote>\n<\/div>\n<p>At some point I will revisit the &#8220;correct&#8221; solution. \u00a0 But if you need to get your stuff to work and don&#8217;t care about calling convention subtleties, then this should work. \u00a0Just be sure to rebuild your boost libraries from scratch after having done this.<\/p>\n<p>I spent a long time trying to figure out this one. \u00a0It was a huge waste of time. \u00a0I hope this solution helps you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes you just don&#8217;t want to bother interfacing with a 3rd-party COM interface doing all the COM-y stuff that&#8217;s required. \u00a0The easiest way is using C++\/CLI and adding a reference to a type library. \u00a0If you happen to have an application that&#8217;s written in C++ and you also happen to use boost::regex, if you do [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-11","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=\/wp\/v2\/posts\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11"}],"version-history":[{"count":3,"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=\/wp\/v2\/posts\/11\/revisions"}],"predecessor-version":[{"id":14,"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=\/wp\/v2\/posts\/11\/revisions\/14"}],"wp:attachment":[{"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.brokencode.tumati.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}