- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试获取 Bloomberg's BDE library在 Visual Studio 2015 中编译。因为它们重新实现了通常由编译器提供的标准库,所以有些头文件的名称与标准库名称完全匹配,例如 stddef.h
.他们可以选择允许您关闭标准库的覆盖,并且为了方便这一点,他们重新实现的文件将选择只包含原始编译器提供的版本,例如 stddef.h
。 .他们通过如下宏来执行此操作:
# if defined(BSLS_COMPILERFEATURES_SUPPORT_INCLUDE_NEXT)
# include_next <stddef.h>
# else
# include BSL_NATIVE_C_LIB_HEADER(stddef.h)
# endif
在哪里BSL_NATIVE_C_LIB_HEADER
扩展成这样:
#if defined(BSLS_PLATFORM_CMP_SUN) // Sun Compiler
# define BSL_NATIVE_C_LIB_HEADER(filename) <../include/filename>
#elif defined(BSLS_PLATFORM_CMP_CLANG) || defined(BSLS_PLATFORM_CMP_GNU)
// Clang and GCC use 'include_next'
#elif defined(BSLS_PLATFORM_CMP_HP) // HP Compiler
# define BSL_NATIVE_C_LIB_HEADER(filename) <../include_std/filename>
#else
// Most other compilers
# define BSL_NATIVE_C_LIB_HEADER(filename) <../include/filename>
#endif
问题是 Visual Studio 2015 introduces some refactoring将 C 标准库头文件的 一些 移动到如下路径:C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt
.这显然意味着 <../include/filename>
将不再找到移动的文件。问题是所有文件都没有移动。例如,iso646.h
还在C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include
并且会被 include 拾取。
所以我的问题简而言之:有没有办法让我继续支持 BSL_NATIVE_C_LIB_HEADER
正在使用宏,同时在幕后确定导入是否应该来自 ../ucrt/
或 ../include
, 基于文件名?我知道我可以创建两个单独的宏,但我宁愿尽可能保持界面相同。
最佳答案
理想情况下,类似于 BSL_NATIVE_C_LIB_HEADER() 的宏将继续工作,而在幕后有一种机制可以根据文件名覆盖某些宏以指向不同的目录。起初这似乎是不可能的,因为宏的参数是一个文件名并且可能包含“.”。或者 ”/”。但是如果有足够多的宏操作,我认为它仍然可以在不更改构建脚本或文件系统的情况下完成。
顺便说一句,我不确定这对 C 预处理器有何影响,但这里...
想法是构建一系列宏,这些宏将插入到 MSVC 2015 特定 block 中的 bsl_stdhdrs_incpaths.h 中。这些宏中有几个基本上做同样的事情,所以我已经分解了解决方案,以便每个用户宏(如 BSL_NATIVE_C_LIB_HEADER)都根据通用宏 FINDER 实现。实现宏的名称很短,便于阅读,它们应该有某种前缀。
警告:这些示例仅在 GCC 4.8.4 和不稳定、clang-3.5 和 MSVC 2015 上进行了测试。
简单的想法
第一个线索是即使参数BSL_NATIVE_C_LIB_HEADER(stddef.h)
包含奇怪的字符,它不是一个单一的 token 。它是列表 {'stddef', '.', 'h'}。
所以我们可以将 stddef#define 到 ../include/stddef 并且它会起作用,因为 '.'并且'h'在扩展后被追加!但更好的是,我们可以使用 ## 将第一个标记粘贴到具有唯一名称的宏中,比如 SELECTOR_stddef
.然后可以使用基于每个文件名的唯一路径#defined:
#define ANGLES(f) <f>
#define BSL_NATIVE_C_LIB_HEADER(file) ANGLES(SELECTOR_##file)
/* each can now have a different prefix */
#define SELECTOR_stddef ../ucrt/stddef
#define SELECTOR_stdarg ../include/stdarg
/* later on, down in the user code... */
#include BSL_NATIVE_C_LIB_HEADER(stddef.h) /* #include <../ucrt/stddef.h> */
#include BSL_NATIVE_C_LIB_HEADER(stdarg.h) /* #include <../include/stddef.h> */
所以这很好用!唯一的问题是每个被调用的文件都必须有一个选择器。如果不是,它将尝试包含一些看起来像 #include <SELECTOR_stdio.h>
的愚蠢文件名。它不会那么好用。一些维护程序员可能会通过向/usr/include 目录中的 SELECTOR_stdio.h 添加一堆符号链接(symbolic link)来“修复”它,这对每个人来说都会很糟糕。
真正 最好的是,如果大多数文件都可以有一个默认值。大多数似乎已被改组到 .../ucrt 中,只有编译器特定的留在 .../include 中。所以最好只覆盖我们想要的那些。但即使是第一种形式,它也可能工作得很好。它的优点是简单。
一堆对此有帮助的 SO 问题:
更完整的解决方案
/* presumably within an #if MSVC 2015 conditional in bsl_stdhdrs_incpaths.h */
#define DELIMITER(a) a
/* same as DELIMITER, but named to distinguish the MSVC __VA_ARGS__ bug */
/* workaround is fine to leave in place for standard compilers */
#define MSVCFIXER(a) a
/* add the angle brackets and re-attach the "rest" tokens */
#define FORMATER(x1, x2, pre, rest, ...) <DELIMITER(pre)rest>
/* if __VA_ARGS__ only has one argument, shift so that pre is the default
* otherwise if __VA_ARGS__ has two, pre is the override */
#define SHIFTER(pre, rest, def, ...) MSVCFIXER(FORMATER(__VA_ARGS__, pre, rest, def))
/* expand the commas */
#define EXPANDER(...) MSVCFIXER(SHIFTER(__VA_ARGS__))
/* main implementation - pass both the selector override and default */
#define FINDER(file, defloc) \
EXPANDER(HEAD_LOC_OVERRIDE_##file, DELIMITER(defloc)file,,)
/* now implement the top level macros */
#define BSL_NATIVE_C_LIB_HEADER(file) FINDER(file, HEAD_LOC_DEFAULT_PREFIX)
#define BSL_NATIVE_SYS_TIME_HEADER(file) FINDER(file, HEAD_LOC_DEFAULT_PREFIX)
#define BSL_NATIVE_CISO646_HEADER(file) FINDER(file, /tmp/)
/* maybe define a common default prefix, or hard code it like iso646
* since most files appear to be in ucrt, make this the default
(file.h) will become <../ucrt/file.h> */
#define HEAD_LOC_DEFAULT_PREFIX ../ucrt/
/* override any other files NOTE: the commas
* (stdarg.h) will become <../include/stdarg.h>
* (stdint.h) will become <../include/stdint.h> */
#define HEAD_LOC_OVERRIDE_stdarg ../include/stdarg,
#define HEAD_LOC_OVERRIDE_stdint ../include/stdint,
/* and you can even override the name part too, or remove or add the .h
* (where.h) will become <../somewhere/when> (note: use two commas)
* (sys/*.h) will become <../include/sys/*.h>
* (cstdio) will become <windows.h> */
#define HEAD_LOC_OVERRIDE_where ../somewhere/when,,
#define HEAD_LOC_OVERRIDE_sys ../include/sys,
#define HEAD_LOC_OVERRIDE_cstdio windows.h,
/* later on, down in the user code... */
#include BSL_NATIVE_C_LIB_HEADER(stdarg.h) /* <../include/stdarg.h */
#include BSL_NATIVE_C_LIB_HEADER(stdio.h) /* <../ucrt/stdio.h */
#include BSL_NATIVE_C_LIB_HEADER(cstdio) /* <windows.h> */
#include BSL_NATIVE_C_LIB_HEADER(what.h) /* <../ucrt/what.h> */
#include BSL_NATIVE_C_LIB_HEADER(where.h) /* <../somewhere/when> */
#include BSL_NATIVE_CISO646_HEADER(iso646.h) /* </tmp/iso646.h> */
关于c++ - 当路径中存在同名文件时,跨平台方式包含系统头文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33793984/
SELECT *, `o_cheque_request.member_id`, `o_cheque_request.wallet_id` FROM `o_cheque_request`, `o_mem
根据某一条件从数据库表中查询 『有』与『没有』,只有两种状态,那为什么在写SQL的时候,还要**SELECT count(*)**呢? 无论是刚入道的程序员新星,还是精湛沙场多年的程序员老白,都是一如
我试图找出一个文件是否存在,如果存在,验证css样式是否已经存在,如果不存在,将它们写在文件末尾... 我已经完成了这一切,但分 3 个步骤: 该文件是否存在? FileInfo fi= new Fi
我们正在开发即时消息传递应用程序,并且需要在用户的化身上用绿点显示用户 friend 的“状态”。 “状态”远远超出了“my_app_is_opened_and_on_focus”,这意味着(我猜可能
模式 Movie(title, year, director, budget, earnings) Actor(stagename, realname, birthyear) ActedIn(stag
我有一个正在尝试创建的 MySQL 触发器,但无法获得正确的语法。 触发器应该遍历一组关键字并将其与插入数据库的新帖子的标题进行匹配。如果找到匹配项,它应该将新帖子分配给该存储桶并更新存储桶的关键字集
我有 3 个表......用户、更新和碰撞。 我想向发出 api 请求的用户返回最新订单的 feed 更新,并提供显示 feed 中每个状态所需的所有数据。我还需要包括更新是否已被发出 api 请求的
我正在尝试呈现一个带有 UIView 的 UIViewController。 以下是我在 viewDidLoad 方法中尝试的代码。 //create the view controller UIVi
我正在努力弄清楚如何在不对 mysql 进行两次调用的情况下从一个表中检查两件事。 我有一个 Members 表。我想测试MemberID 列中是否存在某个值,以及PhoneNumber 列中是否存在
以下代码给出了一个没有 Do Compile 错误的循环: Loop Sheets("Snap").Rows(1).AutoFilter Field:=5, Criteria1:=List
是否可以通过检查“dig”的输出来检查域名的存在? 在绑定(bind)源中,我发现了这些常量: 0 DNS_R_NOEROR 1 DNS_R_FORMERR 2 DNS_R_SERVFAIL 3 DN
Controller 有问题 我在 Windows 上使用服务器,一切正常,但在互联网上我试图访问页面 social_apartament/beauty_life/并且找不到该页面,代码错误 404这
/** This is struct S. */ struct S(T) { static if(isFloatingPoint!T) { /// This version works
JVM 类型删除如何帮助 Clojure?没有它,Clojure 还能存在吗?如果 JVM 有具体化的类型会发生什么?也就是说,Clojure 将如何改变? 最佳答案 Clojure 根本不会有太大变
许多论文等提到对“system()”的调用是不安全且不可移植的。我不反对他们的论点。 不过,我注意到许多 Unix 实用程序都有一个等效的 C 库。如果没有,源可用于各种这些工具。 虽然许多论文和此类
在我的 Node js 应用程序中,我有一个用户登录 api。上面我在服务器端代码中创建了一个名为 customerid 的变量。现在,当用户身份验证成功时。我将他的 userid 值存储在我的 cu
我有一个工作资源管理器组,由 Ubuntu 14.04 虚拟机、网络接口(interface)、公共(public) IP 地址和存储帐户组成。我已经从这组资源中创建了一个模板。 当我尝试部署这组资源
我有一个函数createminor4(arr,锦标赛)它基本上将arr分成4组,每组8人,然后将它们一次交换到tourney 1组。从那里它插入四个{},其中有 4 个带有空数组的键。 我已经在 Ch
我有一个图表,其中有两个图例。我需要更改其中一个图例的点的大小。 我需要更改图例中“市场类型”的项目符号大小。我使用示例 here但不适用于我的图表。 我的代码如下: k <- ggplot(subs
我有 fiddle here展示我正在尝试做的事情。 我有一个动态生成的表,因此列可以按用户选择的任何顺序显示。因此,我尝试获取两个特定 header 的索引,以便可以将 CSS 类添加到这两列以供稍
我是一名优秀的程序员,十分优秀!