我正在编写一个程序,它从已编译的静态库中调用外部字符串数组。
当我在 64位中编译和运行程序时,它可以正常工作。但是,当我在* 32位*中编译代码时尝试调用外部数组时,它在运行main
时会出现分段错误。
以下是代码:
标题声明" hoenyB_lib.h:
#ifndef HONEYB_LIB_H_
#define HONEYB_LIB_H_
#include <string>
extern std::string honeyB_libs[];
#endif
外部定义HoneyB_lib.cpp:
#include <string>
std::string honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" };
外部使用HoneyB_fcn.cpp:
deque<string> get_array()
{
deque<string> dst;
int i =0;
for(;;)
{
if(honeyB_libs[i] == "")
break;
else
{
dst.push_front(honeyB_libs[i]);
i++;
}
}
return dst;
}
编译它的Makefile如下:
all:
$(CC) -c -Wall -fPIC source.cpp
$(CC) -g -c -fPIC honeyB_fcn.cpp
ar rcs libHB.a honeyB_fcn.o
g++ -g -c -fPIC honeyB_lib.cpp
g++ --whole-archive -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a
g++ -L. -o main main.cpp -lHoneyB
调用main()时,这没有问题。但是,当我使用以下代码编译为 32位时:
all32:
$(CC) -m32 -c -Wall -fPIC source.cpp
$(CC) -m32 -g -c -fPIC honeyB_fcn.cpp
ar rcs libHB.a honeyB_fcn.o
g++ -m32 -g -c -fPIC honeyB_lib.cpp
g++ --whole-archive -m32 -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a
g++ -m32 -L. -o main main.cpp -lHoneyB
代码给出了分段错误。如果我将honeyB_fct.cpp
中的呼叫移至honeyB_libs[]
,则代码会编译并执行。
有没有人知道为什么 32位失败了,但适用于 64 ?
提前致谢。
答案 0 :(得分:0)
未定义不同翻译单元之间的初始化顺序。您无法保证HoneyB_lib.cpp
中的全局变量在HoneyB_fcn.cpp
中使用之前会被初始化。它适用于64位版本的唯一原因是因为你很幸运。
有几种解决方法:
honeyB_lib.h
中定义数组,包含在匿名命名空间中以绕过ODR。每个包含标题的TU都有自己的数组副本。作为旁注,我建议使用std::array
而不是原始数组;这样您就可以执行honeyB_libs.size()
(甚至for (auto&& lib : honeyB_libs) {...}
),而不是依赖""
哨兵值,这会稍微清理您的get_array
函数。
答案 1 :(得分:0)
感谢您的帮助。问题似乎与 32位 vs 64-bit 中的字符串位数有关。将 honeyB_libs [] 从字符串数组更改为const char *数组解决了这个问题。 honeyB_lib.h
extern const char* honeyB_libs[];
honeyB_lib.cpp
const char* honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" }
function.cpp
deque<string> get_array()
{
deque<string> dst;
string temp;
int i =0;
for(;;)
{
if(strlen(honeyB_libs[i]) == 0)
break;
else
{
temp = honeyB_libs[i];
dst.push_front(temp);
i++;
}
}
return dst;
}
这样做可以让我的程序编译并运行为 64位和 32位