C++ 工程实践(4):二进制兼容性

陈硕 (giantchen_AT_gmail)

Blog.csdn.net/Solstice

本文主要讨论 Linux x86/x86-64 平台,偶尔会举 Windows 作为反面教材。

C/C++ 的二进制兼容性 (binary compatibility) 有多重含义,本文主要在“头文件和库文件分别升级,可执行文件是否受影响”这个意义下讨论,我称之为 library (主要是 shared library,即动态链接库)的 ABI (application binary interface)。至于编译器与操作系统的 ABI 留给下一篇谈 C++ 标准与实践的文章。

什么是二进制兼容性

在解释这个定义之前,先看看 Unix/C 语言的一个历史问题:open() 的 flags 参数的取值。open(2) 函数的原型是

int open(const char *pathname, int flags);

其中 flags 的取值有三个: O_RDONLY,  O_WRONLY,  O_RDWR。

与一般人的直觉相反,这几个值不是按位或 (bitwise-OR) 的关系,即 O_RDONLY | O_WRONLY != O_RDWR。如果你想以读写方式打开文件,必须用 O_RDWR,而不能用 (O_RDONLY | O_WRONLY)。为什么?因为 O_RDONLY, O_WRONLY, O_RDWR 的值分别是 0, 1, 2。它们不满足按位或

那么为什么 C 语言从诞生到现在一直没有纠正这个不足之处?比方说把 O_RDONLY, O_WRONLY, O_RDWR 分别定义为 1, 2, 3,这样 O_RDONLY | O_WRONLY == O_RDWR,符合直觉。而且这三个值都是宏定义,也不需要修改现有的源代码,只需要改改系统的头文件就行了。

因为这么做会破坏二进制兼容性。对于已经编译好的可执行文件,它调用 open(2) 的参数是写死的,更改头文件并不能影响已经编译好的可执行文件。比方说这个可执行文件会调用 open(path, 1) 来 文件,而在新规定中,这表示 文件,程序就错乱了。

以上这个例子说明,如果以 shared library 方式提供函数库,那么头文件和库文件不能轻易修改,否则容易破坏已有的二进制可执行文件,或者其他用到这个 shared library 的 lib

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 2
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 63
    评论
### 回答1: C++ 中可以使用 STL 库中的 atoi() 和 stoi() 函数将字符串转换为 int 值。 atoi() 函数可以将字符串转换为 int 值, 但它只能转换十进制字符串. stoi() 函数可以将字符串转换为 int 值, 并且可以支持各种进制,如十进制、八进制、十六进制。 如: ``` string str = "123"; int num = atoi(str.c_str()); cout << num << endl; string str2 = "0x11"; int num2 = stoi(str2, nullptr, 16); cout << num2 << endl; ``` 第一个输出为123,第二个输出为17 ### 回答2: 在C++中,可以使用内置的`stoi()`函数将字符串转换为int值,并兼容十进制和十六进制。`stoi()`函数接受一个字符串参数,并返回相应的int值。 要将十进制字符串转换为int值,可以直接调用`stoi()`函数,例如: ```cpp std::string decimalStr = "123"; int decimalInt = std::stoi(decimalStr); ``` 在这个示例中,`decimalStr`是要转换的十进制字符串,`decimalInt`是转换后的int值。 要将十六进制字符串转换为int值,需要在字符串前面加上"0x"前缀,以表示十六进制形式,例如: ```cpp std::string hexStr = "0x1A"; int hexInt = std::stoi(hexStr, nullptr, 16); ``` 在这个示例中,`hexStr`是要转换的十六进制字符串,`hexInt`是转换后的int值。`stoi()`函数的第三个参数为可选参数,用于指定进制,此处使用16表示十六进制。 需要注意的是,如果字符串不是有效的整数格式,或者超出了int类型的范围,将抛出`std::invalid_argument`或`std::out_of_range`异常。因此,在转换之前最好先进行有效性检查。 以上是将字符串转换为int值,兼容十进制和十六进制的方法。如果需要转换其他进制,可以通过更改`stoi()`函数的第三个参数来实现。 ### 回答3: 要将C++字符串转换为int值,并同时兼容不同进制(包括10进制和16进制),可以使用C++的内置函数和一些逻辑处理。下面是代码示例: ```cpp #include <iostream> #include <sstream> #include <string> int convertToInt(const std::string& str) { std::stringstream ss; int value = 0; if (str.substr(0, 2) == "0x") { ss << std::hex << str; // 如果字符串以0x开头,则按16进制处理 } else { ss << str; // 否则按10进制处理 } ss >> value; // 从字符串中提取整数值 return value; } int main() { std::string str1 = "12345"; // 10进制字符串 std::string str2 = "0x1F"; // 16进制字符串 int intValue1 = convertToInt(str1); int intValue2 = convertToInt(str2); std::cout << intValue1 << std::endl; // 输出:12345 std::cout << intValue2 << std::endl; // 输出:31 return 0; } ``` 上述代码中,我们使用了`std::stringstream`类来处理字符串转换。首先判断字符串的开头是否是"0x",如果是,则将其视为16进制字符串;否则将其视为10进制字符串。然后将字符串写入`std::stringstream`对象中,并使用`std::hex`标志设置为16进制。最后通过`<<`运算符提取整数值存储在变量`value`中。最终返回该值。 在`main`函数中,我们传入不同的字符串进行测试。字符串"12345"表示10进制,"0x1F"表示16进制。经过转换后,我们分别获得了相应的整数值,分别为12345和31,并将其输出到控制台上。 这种方法可以兼容不同进制的字符串转换为整数值,因为它根据字符串的开头来决定使用哪种进制进行转换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 63
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈硕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值