问题描述
多个同名类,方法大多相同,数据成员不同。分布在不同的动态库中。并没有导出此类。在Windows上正常,在Linux下崩溃。
崩溃原因
Windows和Linux生成动态库时,导出函数符号的机制不一样。Windows下,如果没有显示指定那个类为导出类,则不会导出此类。
而 Linux下却不是这样。Linux会导出所有的符号。在Linux下,可执行文本调用的导出类就会出现混乱。导致本打算调用A动态库里的导出类,最终调用了B动态库里的导出类。如果导出类的数据成员不相同,就可能导致崩溃。
例子
//mso.cpp
#include <stdlib.h>
#include <stdio.h>
#include "test2.h"
int main()
{
Database db;
int id = db.getID();
printf("id = %d in mso.cpp\n", id);
db.getName();
return 0;
}
//test1.h
#ifndef TEST_1_H
#define TEST_1_H
#include <string>
class Database
{
public:
Database()
:id(0),
defaultName("mysqdl_db")
{}
void getName();
private:
int id;
std::string defaultName;
};
#endif
//test1.cpp
#include <stdlib.h>
#include <stdio.h>
#include "test1.h"
void Database::getName()
{
puts("Start getName in test1.cpp");
printf("test1:db id %d\n", id);
printf("test1:de name %s\n", defaultName.c_str());
puts("End getName in test1.cpp");
}
//test2.h
#ifndef TEST_1_H
#define TEST_1_H
class Database
{
public:
Database();
void getName();
int getID();
};
#endif
//test2.cpp
#include <stdlib.h>
#include <stdio.h>
#include "test2.h"
Database::Database()
{
}
void Database::getName()
{
puts("Test2:db name");
}
int Database::getID()
{
puts("getID in test2.cpp");
return 123;
}
使用如下MakeFile编译,可执行程序运行不会出错
OSFLAG = -shared
CFLAGS = -fPIC
CL = g++
mso:libTest2.so libTest1.so mso.o
$(CL) -o $@ $^ libTest2.so libTest1.so -g -Wl,-rpath,'$$ORIGIN'
#mso:libTest1.so libTest2.so mso.o
# $(CL) -o $@ $^ libTest1.so libTest2.so -Wl,-rpath,'$$ORIGIN'
%.o:%.cpp
$(CL) -c -o $@ $< $(CFLAGS)
libTest1.so:test1.o
$(CL) -o $@ $^ $(OSFLAG)
libTest2.so:test2.o
$(CL) -o $@ $^ $(OSFLAG)
clean:
rm -rf *.o *.so mso
调整连接动态库的顺序,编译。可执行程序运行时崩溃。
OSFLAG = -shared
CFLAGS = -fPIC
CL = g++
#mso:libTest2.so libTest1.so mso.o
# $(CL) -o $@ $^ libTest2.so libTest1.so -g -Wl,-rpath,'$$ORIGIN'
mso:libTest1.so libTest2.so mso.o
$(CL) -o $@ $^ libTest1.so libTest2.so -Wl,-rpath,'$$ORIGIN'
%.o:%.cpp
$(CL) -c -o $@ $< $(CFLAGS)
libTest1.so:test1.o
$(CL) -o $@ $^ $(OSFLAG)
libTest2.so:test2.o
$(CL) -o $@ $^ $(OSFLAG)
clean:
rm -rf *.o *.so mso
执行结果:
getID in test2.cpp
id = 123 in mso.cpp
Start getName in test1.cpp
test1:db id 31496
Segmentation fault (core dumped)
出现这种情况,还有可能不崩溃。可能会窜改其它地方的内存。导致出现一些莫名其妙的问题。这种情况下,崩溃是最好的结果了。