【问题标题】:How to use Boost classes in a .NET C++CLI GUI application如何在 .NET C++CLI GUI 应用程序中使用 Boost 类
【发布时间】:2014-11-21 22:38:09
【问题描述】:

我正在使用 C++CLI 在 Visual Studio 2012 中编写一个 Windows 窗体 GUI 应用程序,我确实需要使用 Boost 双向映射来协调一些 GUI 元素值与一些内部结构中的值。我下载并解压缩了 boost 包,然后在项目的属性菜单中,我将 Boost 位置添加到配置属性 -> VC++ 目录 -> 包含目录。

但是,当我添加 boost 包含时(仅此而已,甚至没有声明 boost::bimap 对象)

#include <boost/bimap.hpp>

我得到错误

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

当我遵循编译错误时,我最终出现在“void_cast_fwd.hpp”和下面包含“BOOST_DLLEXPORT”的行中,但我不确定如何处理它。

#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

我是 .NET 和 C++CLI 的新手,不知道如何更改编译器命令 /clr:pure 或 /clr:safe。

任何关于如何在我的应用程序中使用这个 boost 库的想法将不胜感激。

另外,我现在并不担心可移植性,我只关心它可以在 Windows 上编译。我假设我在 .NET 中使用 C++CLI 比尝试使用 boost 库更多的是可移植性限制,但我也有兴趣听取对此的意见。

谢谢!

【问题讨论】:

  • 我不记得有困难。寻找隐藏__declspec(dllexport) 的定义(BOOST_LIB_* 或类似的)并确保它为您的项目正确定义。你不会暴露你的类型,所以不要导出它们。
  • @sehe 感谢您的快速回复。我对此有点陌生,你能详细说明如何找到隐藏__declspec(dllexport)的定义吗?
  • 跟着编译器报错就好了。库包含__declspec(dllexport) 的机会可能接近于零(因为 Boost Serialization 是一个可移植库)。
  • @sehe 嗯,对不起,但我仍然很困惑。当我遵循编译器错误时,我最终得到了 void_cast_fwd.hpp,当您说“确保为您的项目正确定义它”时,我无法说出我需要做什么。我已经编辑了我的问题以将代码包含在这个 hpp 中。如果你能用“为你的项目正确定义”的意思解释一下,我真的很感激,因为我完全被困在这里了。

标签: .net boost c++-cli


【解决方案1】:

C++/CLI 编译器通常可以确定代码是本机代码还是托管代码。但并非总是如此,并且它具有生成您看到的错误的诀窍。您需要帮助并明确哪些声明是原生的。

首先确保您正确设置了 /clr 选项,您尝试使用的 boost 代码没有什么安全或纯粹的。 Project + Properties、General、Common Language Runtime Support 设置。确保它是普通的 /clr。

然后告诉编译器 boost 头文件包含带有 #pragma 的本机代码:

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

这应该可以解决编译错误。

【讨论】:

    【解决方案2】:

    编译器消息很清楚:您不能从 CLR(或混合模式)程序集中导出本机 DLL 条目。

    因此,指定__delcspec(dllexport) 的代码是非法的。

    Boost Serialization - 也许 - 有助于添加这些可导出项,以便您可以在一个 DLL 中定义可序列化类并从另一个模块反序列化它们(基于运行时类型信息)。

    但是,这不是您目前需要的。

    做什么?

    您需要在代码中找到有问题的声明说明符的位置,并确保它不再试图调皮。

    我非常确信这个特定的声明规范不是硬编码的,而是可能由类似的开关控制的原因

    #define BOOST_SERIALIZATION_WHELPS_IM_NOT_INTERESTED_IN_WIN32_DLL_STUFF_HERE
    

    【讨论】:

    • @river_jones 看这里,我的扩展评论。我希望你能找到最适合你的定义/开关,因为我现在没有时间搜索它(更不用说在我的 Linux 机器上测试它了)。
    • 我看到这篇文章已经过时了,尽管我遇到了同样的问题 - 你有没有想过 _void_cast_fwd.hpp 上是否有一个 Boost 开关来绕过 _DLLEXPORT?很高兴发布另一个问题,但这与我遇到的问题相同(使用 /clr:pure)
    • 我还没找。但是,您可能可以使用 grep 或联系邮件列表中的开发人员(Robert Ramey 通常在附近)。首先,请注意 C++-cli 不在受支持的编译器列表中。
    • @Matt 我注意到汉斯的回答被接受了,直到今天我才看到。汉斯知道他的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    相关资源
    最近更新 更多