在多线程C ++代码中集成遗留C代码

时间:2015-07-05 15:54:32

标签: c++ c multithreading legacy

假设我们有一个遗留的C文件,其中包含一些函数来解决线性方程和几个相应的全局变量。

lineq.c:

/* macro definitions */
...
/* global vars */
...
/* some functions that make use of above variables */
void solveLinEq(...);

现在我们想在现代多线程C ++应用程序中使用这个遗留库。因此,我们想要编写一种包装类LinEqSolver,它提供了一个OO接口来解决线性方程,并在内部调用我们的遗留C库的函数。

但是,应该可能有不同线程使用的LinEqSolver个多个实例。这要求每个实例/每个线程在lineq.c中都有自己的全局变量副本。如果我们不想修改lineq.c

,如何实现这一目标

我能想象的一个可能的解决方案是将全局变量和C文件中的函数复制到类LinEqSolver中,使它们成为数据和函数成员。然后,LinEqSolver的每个实例都将对其前全局变量的私有副本进行操作。但是,这种复制粘贴编程风格相当糟糕,尤其是当lineq.c更新时,我们需要将更改复制粘贴到我们的代码中。

在解决线性方程的实际代码保留在lineq.c并且只是从LinEqSolver调用时,我还有哪些其他的可能性?

3 个答案:

答案 0 :(得分:1)

您可以将lineq.c放入共享对象并使用dlopenRTLD_PRIVATE多次加载,并为每个线程使用dlsym,因此全局变量是独立的每个线程。不幸的是,glibc不支持RTLD_PRIVATE。解决方法是为每个具有不同名称的线程复制共享对象,并使用dlopenRTLD_LOCAL复制到共享对象的副本lineq.cgetElementsByClassName 仍未受到影响。

答案 1 :(得分:1)

您可以使用C ++ 11中的thread_local关键字。如果您的函数始终在开头初始化所有需要的静态变量,这将很有效。

如果你有更复杂的画面 - 将需要更多的工作。例如:

int myVar1, myVar2;

void InitStaticVars()
{
   ....
}

void solveLinEq(...);

如果您只是将thread_local说明符添加到上面的变量并在程序开头调用初始化函数,它将仅为调用线程初始化这些变量。在所有其他线程上,它们的初始值将为零。

答案 2 :(得分:0)

我只想咬紧牙关并修改它以将全局变量添加到一个结构中,该结构应作为指向lineq.c中所有调用的指针传递。

然后很容易用c ++类包装它,每个线程都有一个实例等。

另一种替代方法是修改c文件以使用__declspec(线程)或类似文件。但是,如果您计划将此代码放入dll中,那么您可能会遇到难以解决的问题(至少在Windows上)。