链接多个包含具有等效签名的函数的 C 目标文件

问题描述 投票:0回答:4

假设我有一个 C++ 程序,我想从其中的 C 对象文件调用函数。限制是我不允许对 C 源文件进行任何更改。

在这种情况下,我会将 C 标头作为 extern "C" 包含在我的 C++ 文件中,调用该函数,使用 gcc -c 编译 C 对象,并将结果与实际的 C++ 一起传递给 g++来源。

我想我还会做的是将 C 标头 #include 放在 C++ 文件中命名的 namespace 块中,以保持本地命名空间干净(谁知道 中还有什么其他奇特的东西) .h 文件)。

如果我需要从两个 C 对象文件调用函数,该怎么办?假设他们有不同的签名。但目标文件中也存在一些重复的函数。如果我尝试同时将两个对象传递给 g++,我的链接器此时不会崩溃吗?对于全局变量也是如此。

再次强调:我不允许更改ANY的 C 源代码。否则,我只需将 .c 文件重命名为 .cxx,将其内容和相应标头的内容包装在 namespace bla { } 中,并将所有内容提供给 g++

(是的,C 不是 C++ 的子集,正如评论之一中已经提到的)

c++ c linker
4个回答
2
投票

你的最后一段有一个很好的解决方案 - 为什么不制作一个像这样的 C++ 文件:

namespace c_namespace_1 {
    #include "CFile1.c"
}

namespace c_namespace_2 {
    #include "CFile2.c"
}

依此类推....然后你可以将此文件编译为C++,而不必修改原始源代码。


1
投票

您可以将 C 可执行代码作为单独的二进制数据文件引入,并自行处理函数指针转换 - 基本上完成链接器的工作。 如果二进制文件直接无法工作,请获取 C 文件的汇编程序输出并将它们包装在类似于上述命名空间建议的函数中。


0
投票

如何将每个 C 子系统编译为其自己的 LIB 文件,然后编译一个单独的 C++ LIB 文件,其中包含适当的 C LIB 并仅提供对其 .LIB 中的 C 函数的包装函数调用

即:

file1.c => file1.lib
file2.c => file2.lib

Wrapper1.cpp + file1.lib => Wrapper1.lib
Wrapper2.cpp + file2.lib => Wrapper2.lib

Application.cpp + Wrapper1.lib + wrapper2.lib => Application.exe

请注意,这是我的想法,我不知道链接器是否仍然会繁荣

当然,您可以将 Wrapper1 和 Wrapper2 编译为 dll 而不是 Lib,这将确保链接器不会崩溃!


0
投票

这非常老套,但一种解决方案是通过宏重命名有问题的函数,以便就链接器而言它们具有不同的名称。

例如,如果您有太多名为

foo
的函数,其中一个需要
int
,另一个需要
double
,在文件 IntFoo.c 和 DoubleFoo.c 中,您可以像这样编译它们:

cc -Dfoo=IntFoo -o IntFoo.o IntFoo.c
cc -Dfoo=DoubleFoo -o DoubleFoo.o DoubleFoo.c

然后在你的 C++ 中,你可以这样做:

#define foo IntFoo
extern "C" {
    #include "IntFoo.h"
}

#define foo DoubleFoo
extern "C" {
    #include "DoubleFoo.h"
}

#undef foo

这里有很多注意事项:您必须确保符号

foo
仅用作所需函数的名称,您必须确保在使用符号
foo
的任何地方正确定义宏。 如果存在重复的符号,您还必须为它们定义宏。

仅修复 C 文件可能是更好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.