由于您的库是一个.a
档案库,因此我假设您使用的是某种 UNIX。
全局数组应该有一个与之关联的符号名称。您的工作会更容易或更难,具体取决于描述它的符号类型。
如果有描述这个数组的全局符号,那么你可以直接引用它,例如
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
,然后按上述方法进行操作。
那么如何确定描述该数组的符号是什么?Run 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
,只有第一个是您显然关心的。
声明“外部 int 网格 [];” 并使用它给出一个未定义的引用
这是本地符号的预期:库中的代码类似于:
// foo.c
static char grid[1000];
如果不先将符号全球化,就不grid
能从外部引用它。foo.o
出于安全原因,我不允许在我们的服务器上运行已更改的库二进制文件
我希望你明白这个论点完全是废话:如果你可以将自己的代码链接到那个二进制文件中,那么你可以在服务器上做任何事情(受用户 ID 限制);你已经被信任了。如果服务器管理员不信任您,修改第三方库应该是服务器管理员最不担心的。