在C ++应用程序代码中链接外部定义的静态函数

时间:2018-01-19 06:10:53

标签: c++ c

我有一组预定义的C源代码文件声明定义了很多静态函数 - 它们只是用.c文件编码而不是在任何.h头文件中声明。

现在我试图在我的C ++应用程序代码中使用这些函数:

Cmethods.c

static int amethod(int oppcheck)
{
}

使用C源代码文件创建库:

$ nm --demangle userlib.a | grep amethod
00000000000001b6 t amethod

CppApp.h
extern "C" { int amethod(int oppcheck); }

CppApp.cpp
#include "CppApp.h"

voit callme()
{
amethod(check);
}

但是在编译期间确保userlib.a已链接,我得到以下错误:

: undefined reference to `amethod'

$ nm --demangle userappcode.a | grep amethod
00000000000001b6 t amethod
                 U amethod

我的进一步发现是,对于C源代码文件中的函数,如果在C头文件中声明 - 它们的链接器错误永远不会发生。

注意我无法触及C源代码文件 - 它们由第三方社区提供,我们无法破解许可证。

如何解决问题

4 个答案:

答案 0 :(得分:2)

  

我有一组预定义的C源代码文件,声明定义了很多静态函数。

     

现在我试图在我的C ++应用程序代码中使用这些函数:

从您要从其他translation unit调用的函数中删除static

如果您不能这样做,则无法从外部使用这些功能。编译器甚至可以优化它们,以便从目标文件中删除它们。

(我不推荐的一个肮脏技巧可能是使用gcc -Dstatic=编译该C代码,以使预处理器无需替换static

  

注意我无法触及C源代码文件。

然后你的任务是不可能的。

您可以“扩充”翻译单元,可以通过向他们添加一个名为static public (非static)函数。例如,您可以编译类似

的内容
// include the original C code with only `static` 
#include "Cmethods.c"
// code a public wrapper calling the static method
extern int public_amethod(int oppcheck);
int public_amethod(int oppcheck) { return amethod(oppcheck); }
  

注意我无法触及C源代码文件 - 它们由第三方社区提供,我们无法破解许可证 -

看起来您可能在法律上不允许编译该代码,或者您无法分发其目标文件。 没有技术伎俩来克服法律禁令。如果出现这种情况,你可能会失败!

您的问题不是技术问题,而是社会和法律问题。你可能需要律师。您也可以与原始代码的提供者交谈,并询问他是否被允许做您想做的事。

(没有更多的动力和背景,你的问题看起来很奇怪)

答案 1 :(得分:1)

如果您使用amethod定义static,则该函数将具有内部链接,这意味着您无法将此函数与其他源文件链接。

  

内部联系。

     

该名称可以从中的所有范围引用   现翻译单位。声明的以下任何名称   命名空间范围具有内部链接

     

变量,函数或函数模板声明为static

     

非易失性非内联(sinceC ++ 17)const限定变量   (包括constexpr)没有声明extern,而不是以前   宣布有外部联系。

     

匿名工会的数据成员

答案 2 :(得分:1)

C中的

static函数和C ++中的静态成员函数是两回事。在C中,静态函数仅限于其转换单元和外部不可见,这必不可少的是对象文件(.o / .obj)。

在C ++中,static也可以应用于类的成员函数和数据成员。静态数据成员也称为“类变量”,而非静态数据成员是“实例变量”。

答案 3 :(得分:0)

你可能没有触及C源,但是一个hacky解决方案是#include它到一个不同的翻译单元,其功能可以转发静态。这不是我推荐的一般答案,但......

file1.c中:

static void function1(int)
{ ...}

file2.c中:

#include "file1.c"

void fwd_function1(int x)
{
  function1(x);
}