C++跨平台的坑-重名类导致的崩溃问题

问题描述

多个同名类,方法大多相同,数据成员不同。分布在不同的动态库中。并没有导出此类。在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)


结语

出现这种情况,还有可能不崩溃。可能会窜改其它地方的内存。导致出现一些莫名其妙的问题。这种情况下,崩溃是最好的结果了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值