You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在RHEL编译C++类库时遇链接错误及异常运行行为求助

问题分析:RHEL环境下C++共享库链接错误及运行异常问题

一、链接错误的成因

你遇到的R_X86_64_32重定位错误,核心原因是构建共享库时未生成位置无关代码(PIC):

  • x86_64架构下,共享库需要以位置无关的方式编译,这样加载时可以被映射到进程的任意内存地址。编译时必须添加-fPIC参数,否则编译器会生成依赖固定内存地址的32位重定位指令,而共享库不支持这种重定位类型。
  • 为什么不同printf用法会触发不同结果?这是GCC对printf的特殊优化导致的:
    • 当格式串是极简的"%c"时,编译器会将其直接优化为putchar()调用,不需要在.rodata段存储格式字符串,也就不会触发涉及.rodata的32位重定位,因此能侥幸完成链接。
    • 当格式串包含更多内容或其他转换说明符时,编译器会将格式字符串存入.rodata段,此时未加-fPIC编译的目标文件会生成针对该段的32位重定位,链接共享库时就会触发明确错误:
      /usr/bin/ld: xor.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
      /usr/bin/ld: final link failed: Nonrepresentable section on output
      

你的Makefile编译共享库的命令缺少-fPIC,同时建议用g++链接C共享库(避免gcc链接时遗漏C标准库依赖),正确的构建命令应为:

libxor.so: xor.cpp
    g++ -c -fPIC -o xor.o xor.cpp
    g++ -shared -o libxor.so xor.o

drv: drv.cpp libxor.so
    g++ -o drv drv.cpp -L/home/xxx/source -lxor

二、运行输出异常的原因

能构建的版本(仅用printf("%c", plainText[curSubscript]))输出不符合预期,本质是未加-fPIC编译的目标文件,即使侥幸链接成功,代码存在地址访问错误:

  • 虽然优化后的putchar()调用没触发链接错误,但整个目标文件并非合法的位置无关代码。当共享库被加载到进程内存时,全局变量、数组(比如你的plainText)的地址计算会出现偏差,导致访问到错误的内存位置,输出自然不是预期的字符。
  • 这种“侥幸构建”是编译器优化带来的特例,并非合法的共享库构建方式,运行时的行为完全不可靠。

内容的提问来源于stack exchange,提问作者Paul CyberCitizen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 09:03:19