由于您的库是 .a 存档,因此我假设您使用的是某种 UNIX。
全局数组应该有一个与之关联的符号名称。您的工作会更容易或更难,具体取决于描述它的符号类型。
如果有一个 global 符号来描述这个数组,那么你可以直接引用它,例如
extern char some_array[];
for (int i = 0; i < 100; i++) printf("%2d: 0x%2x\n", i, some_array[i]);
如果符号是本地的,那么你可以先用objcopy --globalize-symbol=some_array将其全球化,然后按照上面的方法进行。
那么如何确定描述该数组的符号是什么?运行objdump -dr foo.o,其中foo.o 包含您知道引用该数组的指令。将出现在引用说明旁边的重定位会告诉您名称。
最后,运行nm foo.o | grep some_array。如果你看到00000XX D some_array,你就完成了——该数组是全局可见的(B 也是如此)。如果看到000XX d some_array,则需要先将其全球化(b 也是如此)。
更新:
objectdump 的 -dr 不起作用
对,因为符号原来是本地的,所以重定位可能是指.bss + 0xNNN。
00000000006b5ec0 b grid
00000000006c8620 b grid
00000000006da4a0 b grid
00000000006ec320 b grid
00000000006fe1a0 b grid
您必须在最终链接的可执行文件上运行 nm,而不是在存档中的单个 foo.o 对象上运行。在您的二进制文件中有五个单独的静态数组,称为grid,只有第一个是您明显关心的。
声明“extern int grid[];”并使用它给出一个未定义的引用
这是本地符号的预期:库中的代码类似于:
// foo.c
static char grid[1000];
如果不首先对符号进行全球化,您将无法从 foo.o 外部引用此 grid。
出于安全原因,我不允许在我们的服务器上运行已更改的库二进制文件
我希望你明白这个论点是完全是废话:如果你可以将你自己的代码链接到那个二进制文件中,那么你可以在服务器上做任何事情(受制于用户 ID 限制);你已经被信任了。如果服务器管理员不信任您,修改第三方库应该是最不担心的。