接口冲突的一种解决方法

问题描述:在一个大的项目中往往会包括很多模块,会有不同的部门或公司来负责实现某个模块,也有可能有第三方或客户的参与。假如他们都用到了某个开源软件,底层模块根据自身的需求对这个开源软件进行了修改或裁减。上层也用到了此开源软件,根据它自己的需求不需要做改动。如果在一个项目中,底层和上层分别同时引入两次此开源软件,就会发生接口冲突。并且底层想对上层隐藏对此开源软件的使用,此时可以通过对接口重命名来解决冲突。

下面举一个简单实例来说明:

1、   首先模拟一个简单的开源库integerArithmetic.lib,实现简单的整数加、减、乘、除运算:包含2个文件,funset.h和funset.cpp,作为上层直接调用;

funset.h:

#ifndef _FUNSET_H_
#define _FUNSET_H_

int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int division(int a, int b);

#endif //_FUNSET_H_

funset.cpp:

#include "funset.h"

int add(int a, int b)
{
	return (a + b);
}

int sub(int a, int b)
{
	return (a - b);
}

int mul(int a, int b)
{
	return (a * b);
}

int division(int a, int b)
{
	if (b == 0) return -1;

	return (a / b);
}

2、   对原integerArithmetic库进行改写,重新生成fbc.lib:包含5个文件,fbc.h, funset.h, rename.h, root.h和funset.cpp,fbc.h为上层提供的接口;

funset.h:

#ifndef _FUNSET_H_
#define _FUNSET_H_

int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int division(int a, int b);

#endif //_FUNSET_H_

funset.cpp:

#include "root.h"

int add(int a, int b)
{
	return (a + b) / 2;
}

int sub(int a, int b)
{
	return (a - b) / 2;
}

int mul(int a, int b)
{
	return (a * b) / 2;
}

int division(int a, int b)
{
	if (b == 0) return -1;

	return (a / b) / 2;
}

rename.h:

#ifndef _DONT_RENAME_
//To avoid any possible linking confliction, rename all exported names

#define add RENAME_add
#define sub RENAME_sub
#define mul RENAME_mul
#define division RENAME_division

#endif //!_DONT_RENAME_

root.h:

#ifndef _ROOT_H_
#define _ROOT_H_

#include "rename.h"
#include "funset.h"

#endif //_ROOT_H_

fbc.h:

#include "root.h"

#define fbc_add add
#define fbc_sub sub
#define fbc_mul mul
#define fbc_division division

3、   新建一个testRename控制台工程,测试这两个库,包含6个文件:testfbc.h, testfbc.cpp, testintegerArithmetic.h,testintegerArithmetic.cpp, stdafx.cpp, testRename.cpp:

testfbc.h:

#ifndef _TEST_FBC_H_
#define _TEST_FBC_H_

void cal_fbc(int a, int b);

#endif //_TEST_FBC_H_

testfbc.cpp:

#include "stdafx.h"
#include "testfbc.h"
#include "../fbc/fbc.h"
#include <iostream>

using namespace std;

void cal_fbc(int a, int b)
{
	cout<<"test fbc lib:"<<endl;
	cout<<"add = "<<fbc_add(a, b)<<endl;
	cout<<"sub = "<<fbc_sub(a, b)<<endl;
	cout<<"mul = "<<fbc_mul(a, b)<<endl;
	cout<<"division = "<<fbc_division(a, b)<<endl;
}

testintegerArithmetic.h:

#ifndef _TEST_INTEGER_ARITHMETIC_H_
#define _TEST_INTEGER_ARITHMETIC_H_

void cal_integerArithmetic(int a, int b);

#endif//_TEST_INTEGER_ARITHMETIC_H_

testintegerArithmetic.cpp:

#include "stdafx.h"
#include "testintegerArithmetic.h"
#include "../integerArithmetic/funset.h"
#include <iostream>

using namespace std;

void cal_integerArithmetic(int a, int b)
{
	cout<<"test integerArithmetic lib:"<<endl;
	cout<<"add = "<<add(a, b)<<endl;
	cout<<"sub = "<<sub(a, b)<<endl;
	cout<<"mul = "<<mul(a, b)<<endl;
	cout<<"division = "<<division(a, b)<<endl;
}

stdafx.cpp:

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

#pragma comment(lib, "../debug/fbc.lib")
#pragma comment(lib, "../debug/integerArithmetic.lib")

testRename.cpp:

#include "stdafx.h"
#include <iostream>
#include "testintegerArithmetic.h"
#include "testfbc.h"

using namespace std;

int main(int argc, char* argv[])
{
	int a, b;

	a = 10;
	b = 2;

	cal_integerArithmetic(a, b);
	cal_fbc(a, b);

	cout<<"ok"<<endl;

	return 0;
}

测试运行,结果正确,这两个库中包含了重名的add, sub, mul, division四个函数,在testRename中同时调用这两个库并没有产生冲突。

使用dumpbin工具查看fbclib.lib,Symbol Name分别为RENAME_add, RENAME_sub, RENAME_mul, RENAME_division;而integerArithmetic.lib中Symbol Name分别为add, sub, mul, division,所以不会产生冲突。

时间: 2024-10-12 21:38:03

接口冲突的一种解决方法的相关文章

jQuery和Prototype的兼容性和冲突的五种解决方法

第一种情况:先加载Prototype,再加载jQuery方法一:jQuery 库和它的所有插件都是在jQuery名字空间内的,包括全局变量也是保存在jQuery 名字空间内的. 使用jQuery.noConflict();主要作用是在任何时候,只要在jQuery加载后就可以调用,将$符号的使用权返回给其它的js库,jQuery在创建它自己的名字空间时就将其它库的$保存在自己的一个变量当中. [html] view plain copy print? <html> <head> &l

Electron与jQuery中$符号冲突的三种解决方法

在Electron工程中引用jQuery时,经常会出现以下错误: Uncaught ReferenceError: $ is not defined 解决的具体方法如下: ①.在测试的过程中(测试过1.10.1,以及当前最新的3.2.1版本都不行),发现只要使用2.03版本的jQuery或者2.2.0版本的jQuery,就不会出现$未定义的情况. ②.使用jQuery原有的关键字jQuery()来替代$(),或者自定义关键字. <script type="text/javascript&q

mysql主从数据库不同步的3种解决方法

mysql主从数据库不同步的3种解决方法 今天发现Mysql的主从数据库没有同步 先上Master库: mysql>show processlist; 查看下进程是否Sleep太多.发现很正常. show master status; 也正常. mysql> show master status; +-------------------+----------+--------------+-------------------------------+ | File | Position |

Django的POST请求时因为开启防止csrf,报403错误,及四种解决方法

Django默认开启防止csrf(跨站点请求伪造)攻击,在post请求时,没有上传 csrf字段,导致校验失败,报403错误 解决方法1: 注释掉此段代码,即可. 缺点:导致Django项目完全无法防止csrf攻击 解决方法2: 在 views.py文件中 #导入,可以使此次请求忽略csrf校验 from django.views.decorators.csrf import csrf_exempt #在处理函数加此装饰器即可 @csrf_exempt def post(request): na

WordPress慢的八种解决方法(用排查法解决)

WordPress的打开速度慢会影响到用户体验和关键词的稳定排名,WordPress为什么加载慢呢?其实很简单的,就是WordPress水土不服,用WordPress的大家都知道,WordPress是外国人开发的,在国内用肯定会卡的,今天笔者给大家整理了几个解决各种WordPress慢的慢的问题,希望能够帮助到大家! 方法一:删除不必要的插件 什么叫不必要的插件呢?就是能用代码解决的就用代码不用插件,不是非常需要的功能类的插件,美化网站的各种插件,常见的久这两种. 方法二:关闭主题的谷歌字体 这

mysql主从数据库不同步的2种解决方法(转)

今天发现Mysql的主从数据库没有同步 先上Master库: mysql>show processlist; 查看下进程是否Sleep太多.发现很正常. show master status; 也正常. mysql> show master status; +-------------------+----------+--------------+-------------------------------+ | File | Position | Binlog_Do_DB | Binlo

iOS Mac忘记登录密码的4种解决方法

4种方法: 一.使用Apple ID重置用户账户密码 使用这个方法有一个前提 如上图红框,此项必须勾选,否则无法使用Apple ID重置密码.(如果你不记得有没有勾选,则你起码要记得首次启动 OS X 或装有 OS X Lion 或更高版本的全新 Mac 时,你会进入“OS X 设置助理”,其中需要你输入 Apple ID.输入 Apple ID 后,请在“创建您的帐户”阶段选择“允许我的 Apple ID 重设此用户的密码”选项.) 好了,来说下具体实现的方法: 如果您在登录窗口错误输入帐户密

OGG的Director web hang住的两种解决方法

OGG的Director web hang住的两种解决方法: OGG的Director web hang住的解释:是指web界面能登陆进去,但是看得刷新日期是很久之前的日期,并且该日期不变化. OGG的Director web hang住 的情况之一: 参考如下的mos文章: Director web displaying "Error 500-Internal Server Error". Domain log has Cannot open paging store. (Doc I

WORD Application.Documents.Open函数返回null的一种解决方法

DCOM Config Setting for "Microsoft Office Word 97 - 2003 Document" 内部配置一切正常,但Application.Documents.Open函数还是返回null.下面是一个解决方法: "C:\Windows\SysWOW64\config\systemprofile\"目录下创建一个"Desktop"目录. WORD Application.Documents.Open函数返回nu