【问题标题】:How to make for that same function into two static Library gcc have differents instances?如何使相同的函数变成两个静态库 gcc 有不同的实例?
【发布时间】:2017-09-07 23:43:25
【问题描述】:

我有一个特殊的情况,使用来自两个不同静态库的函数,是这样的:

我有一个模块“Fun”,它有一个函数“Fun()”和用于工作的静态变量。我有一个静态库“LibA.a”,它有一个使用模块“Fun”的函数“LibA()”。我在静态库“Fun.a”中制作了“Fun”模块。

换句话说:

Fun.a include Func.c

LibA.a include LibA.c and Fun.c

当在主调用中使用 Fun.c 的函数 LibA 时,它从 Fun.a 而不是从 LibA 执行。

问题在于 Fun.c 中的静态变量是从 main 和 LibA 使用的。

是否可以使 LibA 使用包含在库 LibA.a 中的 Fun 而不是 Fun.a 库中的 Fun?因为有两个不同的 Func() 实例。

我做这个例子:

Fun.h

extern int Fun( void );

Fun.c

#include <stdio.h>
#include "Fun.h"

static int value = 0;

int Fun( void )
{
#ifdef FUN
    printf( "Call from Fun.a\n" );
#endif
#ifdef LIBA
    printf( "Call from LibA.a\n" );
#endif

    return value++;
}

LibA.h

extern void LibA( void );

LibA.c

#include <stdio.h>
#include "LibA.h"
#include "Fun.h"

void LibA( void )
{
    printf( "LibA->Fun:%d\n", Fun( ) );
}

main.c

#include <stdio.h>
#include "LibA.h"
#include "Fun.h"

int main()
{
    printf("Lib Example\n");

    LibA( );
    LibA( );
    LibA( );
    printf( "Main->Fun:%d\n", Fun( ) );
    printf( "Main->Fun:%d\n", Fun( ) );
    printf( "Main->Fun:%d\n", Fun( ) );
    LibA( );

    return 0;
}

这个例子的输出是:

Lib Example
Call from Fun.a
LibA->Fun:0
Call from Fun.a
LibA->Fun:1
Call from Fun.a
LibA->Fun:2
Call from Fun.a
Main->Fun:3
Call from Fun.a
Main->Fun:4
Call from Fun.a
Main->Fun:5
Call from Fun.a
LibA->Fun:6

而我想要的输出是这样的:

Lib Example
Call from LibA.a
LibA->Fun:0
Call from LibA.a
LibA->Fun:1
Call from LibA.a
LibA->Fun:2
Call from Fun.a
Main->Fun:0
Call from Fun.a
Main->Fun:1
Call from Fun.a
Main->Fun:2
Call from LibA.a
LibA->Fun:3

为了制作 Fun 静态库,我使用了这个:

gcc-6 -c -x c Fun.c -g2 -gdwarf-2 -o Fun.o" -Wall -O0 -DFUN -std=c11
ar -rsc  libFun.a Fun.o

为了制作 LibA 静态库,我使用这个:

gcc-6 -c -x c Fun.c -g2 -gdwarf-2 -o Fun.o -O0 -DLIBA -std=c11
gcc-6 -c -x c LibA.c -g2 -gdwarf-2 -o LibA.o -O0 -DLIBA -std=c11
ar -rsc  libLibA.a Fun.o LibA.o

为了做主要的例子,我用这个:

gcc-6 -c -x c main.c -g2 -gdwarf-2 -o main.o -O0 -std=c11
gcc-6 -o main.out -Wl,--no-undefined -Wl,-L./ -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack main.o -lFun -lLibA

【问题讨论】:

  • 如果静态库中有多个同名函数定义,链接器将使用它在静态库中可以找到的第一个函数定义。不要滥用它。
  • 亲爱的 Serge,我知道链接器是如何工作的,问题是链接器中是否存在任何参数或解决此问题的其他方法。
  • 不,没有这样的参数。链接器中的所有绑定都是通过链接文件的符号表中的名称完成的。如果您有重复的全局名称。它会混淆链接器。因此,如果您将链接“.o”文件而不是库,则链接器将大声抱怨链接错误。在静态库的情况下,如果找到符号定义,它将不查找符号定义。不过,您可以使用动态库玩一些技巧。

标签: c gcc static-libraries


【解决方案1】:

我找到了问题的答案,如下:

声明 Fun.h 使用隐藏属性

extern __attribute__( ( visibility( "hidden" ) ) ) int Fun( void );

以及编译使用 ld 和 objcopy

gcc -fvisibility=hidden -c Fun.c LibA.c
ld -r Fun.o LibA.o -o LibAx.o
objcopy --localize-hidden LibAx.o
ar rcs LibA.a LibAx.o

当我编译包含 Fun.c 和 LibA.a 的 main.c 时,输出为:

Lib Example
Call from LibA.a
LibA->Fun:0
Call from LibA.a
LibA->Fun:1
Call from LibA.a
LibA->Fun:2
Call from App
Main->Fun:0
Call from App
Main->Fun:1
Call from App
Main->Fun:2
Call from LibA.a
LibA->Fun:3

我在这个链接https://stackoverflow.com/a/30028576/5011611找到了解决方案

感谢https://stackoverflow.com/users/103855/ypsu

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2013-10-16
    • 2022-08-09
    • 1970-01-01
    相关资源
    最近更新 更多