【发布时间】:2014-07-05 10:57:49
【问题描述】:
我的环境是 Visual Studio 2008。
我有 3 个不同的库。概括起来,它们的行为等价如下。
库 1 - 提供要注册的功能
class FunctionRegistry
{
typedef std::list<int> TListInt;
TListInt m_Params;
void * m_FPtr;
public:
FunctionRegistry(void * fptr):m_FPtr(fptr){}
FunctionRegistry& Insert(int value){m_Params.push_back(value); return *this;}
void Call();
};
void FunctionRegistry::Call()
{
/*this is the area I want to get rid of */
TListInt::iterator ite = m_Params.begin();
while (ite != m_Params.end());
{
__asm push *ite;//I want to remvoe this assmebly code somehow
++ite;//Edited after initial post
}
((void(*)())m_FPtr)();
ite = m_Params.begin();
while (ite != m_Params.end());
{
int i = 0;
__asm pop i;//I want to remvoe this assmebly code somehow
++ite;//Edited after initial post
}
/*end of area to get rid of*/
}
Library 2 - 定义一组函数,如
void foo(int i, int j)
{
std::cout << "foo int int " << i << " " << j << std::endl;
}
void bar(int i)
{
std::cout << "bar int " << i << std::endl;
}
void biz()
{
std::cout << "biz" << std::endl;
}
FunctionRegistry fRegFoo((void*)&foo);
fRegFoo.Insert(10).Insert(20);
FunctionRegistry fRegBar((void*)&bar);
fRegBar.Insert(10);
FunctionRegistry fRegBiz((void*)&biz);
库 3 - 这是上述两个库的用户,示例用法如下,
fRegFoo.Call();
fRegBar.Call();
fRegBiz.Call();
这是一个遗留代码,我现在正试图摆脱上述汇编代码。我可以轻松更改(通过一些 API 更改)我的库 1 来满足我的需要。但是我的问题是,由于库在大量用户中的大量分布,要求他们根据库 1 的 API 更改来更改他们的用例(这里是库 3)应该是我最后的选择。
现在,我正在寻求您的帮助,有没有什么方法可以使用任何可能的技术来更改我的 library 1 内部结构,而无需更改其 API 以消除此汇编代码?
如果您认为不更改任何 API 就无法实现,请建议对库 3 的代码更改最少的方法。
【问题讨论】:
-
如果你知道
m_Params.size()总是相当小(比如 vector<int>)。 -
呼应@david.pfx 所说的:您必须保留的已发布API 到底是什么?如果它只是图书馆 3,那是微不足道的。
-
@KerrekSB API 几乎与库 1 类似,但功能较少。但不平凡的情况是到处改变图书馆的使用。在数百个跨越大量用户中。这就是为什么我最初提到,要求我的所有用户根据我的更改更改他们的代码,这将是“我最后的选择”。我正在寻找最后一个选项之前的选项(如果有的话)。
-
可能只是我,但我仍然完全不清楚您的要求和限制。您的问题表明用户只能看到 Library 3,但您的 cmets(以及您发布此问题的事实)表明 Library 1 的内部工作方式也以某种方式公开。我无法理解这一点,也不知道这个问题的“正确”答案应该是什么样子。
-
让我借用Raymond 的精神力量,看来您的库正在尝试为模仿CDECL 调用Dispatcher。最直接的解决方案是使用内在函数,但 push 和 pop 没有内在函数。不幸的是,这不是一项简单的任务,您可以将 asm 代码移动到外部文件并使用 MASM 进行编译。对于这么小的代码,IMO 太多了。
标签: c++ visual-studio assembly function-pointers