C语言调用自定义共享库无法返回正确内存地址如何解决
根本原因
这是64位C程序开发中非常典型的隐式函数声明导致的指针截断问题:
- 你的主程序调用共享库中返回堆地址的函数时,没有提前声明该函数的原型,C标准默认会将未声明函数的返回值判定为32位有符号
int类型 - 64位系统下指针长度为8字节,返回的指针值会先被截断为4字节的
int,再做符号扩展为8字节的指针值。你遇到的低4字节为0xaff662a0,其最高位为1,符号扩展时高位会全部补1,最终就得到了0xffffffffaff662a0的错误地址 - 直接
#include "mem.c"时相当于把共享库代码直接嵌入主程序编译,编译器可以直接获取函数的返回值类型,不会出现截断问题
无需包含mem.c/mem.h的解决方案
你可以选择以下任意一种方法解决:
- 在主程序代码开头手动声明共享库导出函数的完整原型,假设你获取堆地址的函数为
void* get_sim_heap(),只需添加一行声明即可:
其余共享库导出的函数也按照实际返回值和参数补全声明,就可以正常获取正确地址void* get_sim_heap(); - 编译主程序时添加
-Wall编译参数,可以第一时间发现隐式函数声明的警告,避免同类问题出现:gcc main.c -lmem -L. -o main -Wall - 如果使用C99及以上标准编译,隐式函数声明会被判定为编译错误,可以直接从编译环节阻断该问题:
gcc main.c -lmem -L. -o main -std=c11
内容的提问来源于stack exchange,提问作者humbleLearner
相关产品推荐
相关产品推荐

