如何将 Visual Studio 宏值放入预处理器指令中?

2024-04-09

在我的项目中,我需要访问的价值$(SolutionDir)运行时的宏。为此,我尝试添加预处理器条目,例如DEBUG_ROOT=$(SolutionDir) or DEBUG_ROOT=\"$(SolutionDir)\"但这会由于无效的转义序列而导致各种编译器错误,因为$(SolutionDir)包含单个\字符(例如$(SolutionDir) = c:\users\lukas\desktop\sandbox\).

有没有一种简单的方法来传递值$(SolutionDir)宏到我的代码中?

背景

我正在利用函数OutputDebugString(..)我的调试版本中有很多内容是为了查看我的代码正在做什么。

/* debug.h */
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define LOCATION __FILE__ "(" TOSTRING(__LINE__) ") : "

#if !defined(DEBUG_ROOT)
#define DEBUG_ROOT    "#"   /* escape string to force strstr(..) to fail */
#endif

/*
**  DBGMSG macro setting up and writing a debug string.
**  Note: copying the strings together is faster than calling OutputDebugString(..) several times!
**  Todo: Ensure that size of dbgStr is not exceeded!!!
*/
#define DBGMSG(text) \
    { \
        char dbgStr[1024]; \
        char *pFile; \
        pFile = strstr(LOCATION, DEBUG_ROOT); \
        if (pFile == LOCATION) \
        { \
            wsprintf(dbgStr, ".%s", pFile + strlen(DEBUG_ROOT)); \
        } \
        else \
        { \
            wsprintf(dbgStr, "%s", LOCATION); \
        } \
        wsprintf(dbgStr, "%s%s", dbgStr, text); \
        OutputDebugString(dbgStr); \
    }


/* somewhere in the code */
DBGMSG("test")

使用截图会导致打印输出像c:\users\lukas\desktop\sandbox\testconsole\main.c(17) : test在 Visual Studio 的输出窗口中。这可以加快在代码中查找导致打印输出的位置,因为您只需双击输出窗口的行,Visual Studio 就会自动跳转到指定的代码位置。

因为根据解决方案的位置,绝对路径 (__FILE__扩展为绝对路径)调试字符串的“标头”可能会变得相当长。我发现 Visual Studio 足够聪明,可以理解相对路径,例如解决方案根目录。为了减少字符串的长度,我正在检查是否__FILE__是在一个DEBUG_ROOT目录,如果是的话我要替换DEBUG_ROOT用一个简单的'.'生成相对路径DEBUG_ROOT。所以如果我写#define DEBUG_ROOT "c:\\users\\lukas\\desktop\\sandbox"上面示例的最终调试字符串将是.\testconsole\main.c(17) : test。目前我正在设置的值DEBUG_ROOT在项目的预处理器定义内。

由于有几个人正在处理该项目,因此在项目设置中拥有绝对路径并不是明智之举,因为每个团队成员都可能将源文件签出到不同的根目录。所以我尝试使用$(SolutionDir)宏来创建类似的东西DEBUG_ROOT=\"$(SolutionDir)\\"。但这样做我就会遇到麻烦。自从$(SolutionDir) = c:\users\lukas\desktop\sandbox\扩大的DEBUG_ROOT导致未定义的转义序列、未终止的字符串和更多丑陋的编译器错误......

Solution

根据以下的回答kfsone https://stackoverflow.com/users/257645/kfsone我提出了以下解决方案,可以传递 Visual Studio 宏的任何值,例如$(SolutionDir)到你的代码中。以下解决方案与所使用的 Visual Studio 版本和语言 C/C++ 无关。

Adding SOLUTION_DIR=\"$(SolutionDir)"项目的预处理器条目会产生一个编译器命令行,如下所示:

/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "SOLUTION_DIR=\"C:\Users\Lukas\Desktop\sandbox\""
/Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /Wp64 /ZI /TP
/errorReport:prompt

注意$(SolutionDir)前面有一个\"创建一个"值前面的字符$(SolutionDir)但由单个终止"。查看编译器的命令行显示终止"被最后一个逃脱\ of $(SolutionDir).

Using SOLUTION_DIR在您的代码中会导致未知的转义序列,并且字符串以所有结尾\字符被删除。这是由编译器完成的,它扩展了SOLUTION_DIR并解释\作为转义序列的开始。

使用TOSTRING(x)上面发布的代码宏解决了这个问题,因为它强制编译器按原样使用字符串而不进行进一步处理。

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#define SOLUTION_DIR2   TOSTRING(SOLUTION_DIR)

// the following line may cause compiler warnings (unrecognized character escape sequence)
printf("%s\n", SOLUTION_DIR);    // prints C:UsersLukasDesktopsandbox 

// the following line compiles without any warnings
printf("%s\n", SOLUTION_DIR2);   // prints "C:\Users\Lukas\Desktop\sandbox"

从这里开始,只需执行一些字符串魔术即可删除"字符来自SOLUTION_DIR2.


Visual Studio 2013 及更高版本中提供了一项 C++11 功能(原始字符串文字),可让您执行此操作。语法是

'R"' <delimiter> '(' <string> ')' <delimiter> '"'

例如如果你选择“?:?”作为你的分隔符

R"?:?(don't\escape)?:?"

或者如果您选择“Foo123”

R"Foo123(don't\escape)Foo123"

但对于这个演示,我要选择?作为单字符分隔符,因为我们知道它在 Windows 文件名中是非法的。

现在您可以设置项目级预处理器定义:

DIR=R"?(C:\\Temp\\)?"

然后以下代码生成预期的输出

#include <iostream>
int main() {
    std::cout << DIR << '\n';
}

writes

C:\\Temp\\

代替

C:\Temp\

现在捕获 SolutionDir 宏就很简单

DIR=R"?($(SolutionDir))?"

如果这很麻烦,您可以在属性表中添加自定义宏。转到“属性资源管理器”并右键单击您的项目,添加一个新的属性表,将其命名为“ProjectMacros.props”或其他名称。

展开您的项目并选择其中一种配置,例如调试,双击“PropertySheet”值打开“PropertySheet PropertyPages”并选择“UserMacros”

点击“添加宏”

Name: RawSolutionDir
Value: R"?path?($(SolutionDir))?path?"

您现在应该能够使用预处理器条目

SOLUTIONDIR=$(RawSolutionDir)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 Visual Studio 宏值放入预处理器指令中? 的相关文章

  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框

随机推荐

  • 所有其他 Visual Studio“运行测试”尝试都会导致“无法启动程序 QTAgent32.exe”

    每当我运行测试 然后尝试再次运行测试时 都会收到以下错误 无法对测试运行进行排队 无法启动程序 C Program Files x86 Microsoft Visual Studio 10 0 Common7 IDE QTAgent32 e
  • 不幸的是应用程序已停止工作

    我是 Android 应用程序开发新手 我正在做这个教程应用程序 这是一个非常简单的应用程序 它从计数器中加一并减一 当我在模拟器中运行它时 它说 不幸的是教程已停止工作 代码中没有错误 API 级别是 17 请帮助我 java代码 pub
  • jquery isotope 具有无限滚动和图像预加载器

    我正在使用 jquery 同位素和无限滚动 并且想要使用图像预加载器 我使用的图像预加载器是这样的 图像预加载器 http code google com p img preloader image preloader loader ima
  • 在 Swift 上设置计时器

    我尝试重复执行函数 pepe 我没有收到错误 但它不起作用 这是我的代码 public class MyClass var timer Timer objc func pepe gt String let hola hola return
  • 对 Firebase Auth 帐户的密码实施自定义规则

    当用户创建帐户时 有什么方法可以设置密码的自定义规则吗 Firebase 似乎没有提供编辑密码规则的方法 我知道我可以在前端设置密码规则 但就像弗兰克 范普费伦 https stackoverflow com a 36319652 6516
  • Firefox 在重新加载时保留表单数据

    I have a big problem with the functionality in Firefox that keeps data that the user have filled in on reload F5 If i us
  • 从ini文件中读取数据

    我有一个需要输入文件名的 vbscript 代码是 Dim tsout Set tsout gofs CreateTextFile C csv Dim tsin Set tsin gofs OpenTextFile C csv 我该如何配置
  • Pandas 找到行的子集,在其他列约束下最小化列的总和

    我有一个非常简单的想法 即找到行的子集 使一列的总和最小化 而另一列的总和必须大于某个值 Example df pd DataFrame Names a b c d e f Target 35 15 12 8 7 5 Cost 15 40
  • DB 中的 Twitter 名称长度

    我正在向成员表添加一个字段 用于存储网站上成员的 Twitter 名称 据我所知 twitter 名称的最大长度为 20 因此显然我应该将字段大小设置为 varchar 20 SQL Server 这是一个好主意吗 如果 Twitter 开
  • 无法使用 Terraform 创建 google 项目

    我正在关注Google GKE 和 SQL 与 terraform https medium com mudrii google gke and sql with terraform 294fb84061教程 但我无法创建一个google
  • 如何将 AutoFixture 自定义应用到从基类继承的任何内容?

    为了干燥我的单元测试 我尝试使用 AutoFixture 作为 IoC 容器来实例化我的被测系统 SUT 在本例中是 ASP NET MVCControllers 因此 我想自定义 AutoFixture 以创建没有自动属性的控制器 我尝试
  • 获取 pandas 列中的第一和第二最高值

    我正在使用 pandas 来分析一些选举结果 我有一个 DF 结果 其中每个选区都有一行 代表各个政党 超过 100 个 的选票的列 In 60 Results columns Out 60 Index Constituency Regio
  • 如何在 Ubuntu 中为 Android 设置 Appium

    我是新来的appium 自动化测试技术 我使用的是运行 Ubuntu Linux 的 PC 我已经搜索过这个主题 但没有得到任何有用的教程 谁能指出我正确的文档 不要通过apt get安装nodejs 这需要sudo权限 如果以sudo用户
  • 如何使用 Mock.Of() 模拟没有默认构造函数的类?

    使用起订量 我需要在现有的基础上创建一个假的class 不是接口 有没有默认的ctor 我可以使用 传统 语法来做到这一点 var fakeResponsePacket new Mock
  • 当绑定属性更改时,ListView 分组不会更新

    我正在使用依赖项属性 GroupDescription 根据列表视图项目源的属性对 WPF 列表视图中的项目进行分组 我的问题是 仅当 GroupDescription 值更改时才会更新分组 而不是在列表视图源中项目的绑定属性更改后分组才会
  • iOS 6 中视图控制器的旋转不正确

    在我的应用程序中 我一直在使用现已弃用的 shouldAutoRotateToFace 方法 现在 当使用 iOS 6 模拟器时 当设备处于横向时 我的所有子视图都会旋转到纵向 有谁知道这可能是什么原因造成的 我已经尝试使用supporte
  • 将 Firebase Analytics 添加到 Instant App

    我正在将现有应用程序转换为 Android Instant App 我已经成功地做到了这一点 我的应用程序以即时应用程序形式运行 我现在面临的问题是关于 Firebase Analytics 当我运行即时应用程序时 出现此错误 E Fire
  • :: 运算符必须与 tolower() 一起使用吗?

    transform mystr begin mystr end mystr begin tolower 我正在使用转换函数使字符串全部小写字母 但即使在编写 using namespace std 之后在我的程序顶部 我收到一大堆错误 当像
  • 如何使用 Python 从网页的检查元素中获取数据

    我想使用 Python 从检查元素获取数据 我可以使用 BeautifulSoup 下载源代码 但现在我需要来自网页的检查元素的文本 如果您能建议我如何去做 我将不胜感激 编辑 我所说的检查元素是指 在谷歌浏览器中 右键单击为我们提供了一个
  • 如何将 Visual Studio 宏值放入预处理器指令中?

    在我的项目中 我需要访问的价值 SolutionDir 运行时的宏 为此 我尝试添加预处理器条目 例如DEBUG ROOT SolutionDir or DEBUG ROOT SolutionDir 但这会由于无效的转义序列而导致各种编译器