How to use Boost classes in a .NET C++CLI GUI appl

2019-08-07 09:16发布

问题:

I am writing a Windows Forms GUI application in Visual Studio 2012 using C++CLI and I really need to use the Boost bidirectional map to coordinate some GUI element values with values in some internal structs. I downloaded and unzipped the boost package and then in my project's Properties menu I added the Boost location to Configuration Properties -> VC++ Directories -> Include Directories.

But, when I add the boost include (and nothing else, not even declaring a boost::bimap object)

#include <boost/bimap.hpp>

I get the errors

error C3389: __declspec(dllexport) cannot be used with /clr:pure or /clr:safe
error C3395: 'boost::serialization::void_cast_register' : __declspec(dllexport) cannot be applied to a function with the __clrcall calling convention

When I follow the compile errors I end up in "void_cast_fwd.hpp" and on the line below that contains "BOOST_DLLEXPORT" but I'm not sure what to do with it.

#ifndef  BOOST_SERIALIZATION_VOID_CAST_FWD_HPP
#define BOOST_SERIALIZATION_VOID_CAST_FWD_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// void_cast_fwd.hpp:   interface for run-time casting of void pointers.

// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com . 
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// gennadiy.rozental@tfn.com

//  See http://www.boost.org for updates, documentation, and revision history.

#include <cstddef> // NULL
#include <boost/serialization/force_include.hpp>

namespace boost {
namespace serialization {
namespace void_cast_detail{
class void_caster;
} // namespace void_cast_detail
template<class Derived, class Base>
BOOST_DLLEXPORT 
inline const void_cast_detail::void_caster & void_cast_register(
    const Derived * dnull = NULL, 
    const Base * bnull = NULL
) BOOST_USED;
} // namespace serialization
} // namespace boost

#endif // BOOST_SERIALIZATION_VOID_CAST_HPP

I am new to .NET and C++CLI and not sure how to change the compiler commands /clr:pure or /clr:safe.

Any thoughts on how I can use this boost library in my application would be greatly appreciated.

Also, I am NOT worried about portability right now, all I care is that it compiles on Windows. I am assuming the fact that I am using C++CLI in .NET is more of a portability restriction than trying to use boost libraries, but am interested to hear opinions on this too.

Thank you!

回答1:

The C++/CLI compiler can usually figure out whether code is native or managed. But not always, and that has a knack for generating the errors you see. You need to help and be explicit about what declarations are native.

First make sure you have the /clr option set correctly, there is nothing safe or pure about the boost code you are trying to use. Project + Properties, General, Common Language Runtime Support setting. Ensure it is plain /clr.

Then tell the compiler that the boost headers contain native code with a #pragma:

#pragma managed(push, off)
#include #include <boost/bimap.hpp>
#pragma managed(pop)

That ought to take care of the compile errors.



回答2:

The compiler message is clear: you cannot be exporting native DLL entries from a CLR (or mixed mode) assembly.

Therefore, the code that specifies __delcspec(dllexport) is outlawed.

Boost Serialization is - perhaps - helpfully adding these exportables so that you can define serializable classes in one DLL and deserialize them from another module (based on the runtime type information).

However, this is not what you require at the moment.

What Do?

You need to find the spot in the code that has the offending declaration specifier and make sure that it doesn't try to be naughty anymore.

The reason I'm quite confident that this particular declaration specification is not hardcoded, but likely governed by a switch like

#define BOOST_SERIALIZATION_WHELPS_IM_NOT_INTERESTED_IN_WIN32_DLL_STUFF_HERE