我需要在 VxWorks 中运行 C 程序的多个实例(VxWorks 有一个全局命名空间)。问题是 C 程序定义了在全局命名空间中冲突的全局变量(旨在供该程序的特定实例使用)。为了完成这项工作,我想对程序进行最小的更改。欢迎所有想法!
问候
顺便说一句……现在不是提及全局变量不是最佳实践的好时机!
我需要在 VxWorks 中运行 C 程序的多个实例(VxWorks 有一个全局命名空间)。问题是 C 程序定义了在全局命名空间中冲突的全局变量(旨在供该程序的特定实例使用)。为了完成这项工作,我想对程序进行最小的更改。欢迎所有想法!
问候
顺便说一句……现在不是提及全局变量不是最佳实践的好时机!
最简单的做法是使用任务变量(参见 taskVarLib 文档)。
使用任务变量时,该变量特定于当前上下文中的任务。在上下文切换时,存储当前变量并加载新任务的变量。
需要注意的是,任务变量只能是 32 位数字。每个全局变量也必须独立添加(通过它自己对 taskVarAdd 的调用?),它还增加了上下文切换的时间。
此外,您将无法与其他任务共享全局变量。
您不能将任务变量与 ISR 一起使用。
另一种可能性:
如果您使用的是 Vxworks 6.x,您可以制作一个 Real Time Process 应用程序。
这遵循一个进程模型(类似于 Unix/Windows),其中程序的每个实例都有自己的全局内存空间,独立于任何其他实例。
另一种可能的解决方案是将应用程序的全局变量放在静态结构中。例如:
从:
int global1;
int global2;
int someApp()
{
global2 = global1 + 3;
...
}
TO:
typedef struct appGlobStruct {
int global1;
int global2;
} appGlob;
int someApp()
{
appGlob.global2 = appGlob.global1 + 3;
}
这只是在您的应用程序代码中变成了搜索和替换。代码结构没有变化。
在集成来自同一供应商的两个第三方库时,我必须解决这个问题。两个库都使用了一些相同的符号名称,但它们彼此不兼容。因为这些来自供应商,我们无法搜索和替换。并且任务变量也不适用,因为(a)两个库可能从同一个任务中调用,并且(b)一些欺骗符号是函数。
假设我们有 app1 和 app2,分别链接到 lib1 和 lib2。两个库都定义了相同的符号,因此必须彼此隐藏。
幸运的是(如果您使用 GNU 工具)objcopy 允许您在链接后更改变量的类型。
这是解决方案的草图,您必须根据需要对其进行修改。
首先,为 app1 执行部分链接以将其绑定到 lib1。在这里,我假设您已经将 app1 中的 *.o 部分链接到 app1_tmp1.o。
$(LD_PARTIAL) $(LDFLAGS) -Wl,-i -o app1_tmp2.o app1_tmp1.o $(APP1_LIBS)
然后,在您刚刚创建的 tmp2 对象中隐藏 lib1 中的所有符号,以便为 app1 生成“真实”对象。
objcopymips `nmmips $(APP1_LIBS) | grep ' [DRT] ' | sed -e's/^[0-9A-Fa-f]* [DRT] /-L /'` app1_tmp2.o app1.o
对 app2 重复此操作。现在你已经准备好 app1.o 和 app2.o 链接到你的最终应用程序,没有任何冲突。
此解决方案的缺点是您无法从主机外壳访问任何这些符号。要解决此问题,您可以暂时关闭其中一个或另一个库的符号隐藏以进行调试。