C语言 在Visual Studio中编写静态库时如何控制导出的符号?

tjvv9vkg  于 2023-03-12  发布在  其他
关注(0)|答案(2)|浏览(222)

我想建立一个静态库,它有一些函数/变量/等导出,其他的由库内部使用。导出的一切都是C风格的。
如何做到这一点?
我所尝试的如下:
MyLib.h

int Test(int a, int b);

MyLib.cpp

#include "MyLib.h"
int Private(int a, int b)
{
    return a * b;
}
int Test(int a, int b)
{
    return Private(a, b);
}

我是这样使用这个库的:
Main.cpp

#include "MyLib.h"
int main()
{
    int x = Test(4, 6);
    ...
}

所有这些似乎都运作良好。
但是,我发现函数Private也被导出了。
因此,以下代码也将编译和链接:
Main.cpp

#include "MyLib.h"
int Private(int a, int b);
int main()
{
    int x = Private(4, 6);
    ...
}

因此,我猜想我已经污染了全局名称空间,现在我无法在Main.cpp中定义一个名为Private的函数,因为链接器会抱怨这个符号已经存在。
那么,如何控制哪些函数/变量/符号对使用库的代码可见呢?
在做了一些搜索之后,我发现在MyLib.cpp中声明Private函数为static似乎可以解决这个问题。但是,我不确定这是否是最好的方法。对我来说,“标记”那些我想导出的符号比“标记”那些我想隐藏的符号更有意义,因为我只想导出所有符号中的一小部分。

6fe3ivhb

6fe3ivhb1#

简化版:
操作系统不能将静态库识别为它所理解的任何东西。它只处理exe文件、dll文件和数据文件。您可以构建一个静态库来将其合并到一个或多个exe文件和|或dll的,基本上是为了保存重新编译它为每个。
因此,期望您能够访问所有代码|生成链接到的exe或dll时,静态库中的数据。
相反,exe|dll可以由操作系统应用安全性,并被视为“最终产品”,因此默认情况下,除非显式标记为导出,否则所有内容都是私有的。
所以,要么:

  • 使用一个静态库并把所有的“私有内容”放在一个.cpp中,例如,像你发现的那样标记为静态的,或者放在一个匿名的命名空间中,或者...
  • 使用dll并将所有“公共内容”标记为导出。
w41d8nur

w41d8nur2#

static int Private(int a, int b)
{
    return a * b;
}

相关问题