关于静态和共享库的C问题

时间:2016-06-24 15:46:07

标签: c shared-libraries static-libraries

我有一些 .c .h 文件,主要功能封装在MAIN_FUNC.c中。我需要将它们传递给一个将MAIN_FUNC()与他的文件集成的人。

然而,由于我的算法是保密的,我不能只发送 .c .h 文件,所以我一直在研究静态和共享库。不过我还是有些疑惑。

1:在我看过的每个教程中都需要 .h 。有什么办法我可以在他的代码中发送一个他可以#include的单个库文件吗?

2:即使我必须传递 .h 的文件,我真的需要传递所有文件吗?我怎样才能只给他libMAIN_FUNC.a和MAIN_FUNC.h?

3:使用 .a .so 库,有没有办法对文件进行逆向工程,以便人们可以看到 .c .h 代码?

4 个答案:

答案 0 :(得分:2)

  1. 不,你必须向他提供至少一个.h文件。
  2. 不,您只需要传递足够定义库和用户之间接口的那些。我建议你阅读pimpl范例
  3. 理论上是的,您的 .a .so 文件可以进行逆向工程,但这非常重要。

答案 1 :(得分:2)

我的理解是你有一个其他人将要实现的.c和.h文件,但你想保密你的代码。

如果您唯一关心的是分发源代码,那么总会有部分编译选项。如果您遇到了确保代码无问题的麻烦,可以将程序部分编译为.o文件。

我不知道您的代码的详细信息,但如果您提到的其他人只是像图书馆一样实现您的功能,那么.o就是他所需要的。

为您结束的示例makefile:

all: MAIN_FUNC.o

MAIN_FUNC.o: MAIN_FUNC.c MAIN_FUNC.h
    gcc -c MAIN_FUNC.c

其他人的样本makefile结束:

all: main

main: main.c main.h MAIN_FUNC.o
    gcc -o main.c MAIN_FUNC.o main

为了保护自己的财产,很多公司都会这样做。当一家公司将软件销售给另一家公司时,他们经常会销售这些.o文件。您只需要提供函数所做的知识(即"此函数从控制台获取输入并返回写为整数的字数") - 允许实现的基本内容你的工作没有透露你的源代码。

编辑:修正了一个拼写错误

答案 2 :(得分:1)

1)您可以将C文件编译成库(*.a或其他),前提是它已正确编写并与h文件一起分发。你必须提供h文件,因为它们是你的库的接口,否则它只是一个二进制blob。

2)您需要传递标头,声明您的库正在导出的公共接口。即您希望库用户有权访问的功能和符号。

3)是的,总有一种方法可以对任何东西进行逆向工程。唯一的问题是增益/努力比。

答案 3 :(得分:1)

首先,关于逆向工程。给定无限的时间和资源,您的代码始终可以进行逆向工程。话虽如此,您的目标是让其他人对您的代码进行逆向工程变得不切实际。

现在回答你的问题: 从c代码生成可执行二进制文件发生在“两个主要”步骤中。编译和链接。 编译后,您的files.c成为目标文件(机器代码)。它们还不可执行。

如果您有两个文件:file1.c和file2.c,您将获得file1.o和file2.o。

现在,file1.c中的代码可能正在调用file2.o中存在的函数。在编译阶段,file1.c需要知道的是函数原型。

当调用链接器生成可执行二进制文件时,它确保从file1.o调用的函数存在于某处,例如file2.o。

这对您有何影响:

头文件不应该是专有的(但可能是出于法律原因)。头文件主要用于告诉其他.c文件什么函数和返回值(声明,而不是实现)。

现在也许您有一些专有的函数原型,无论出于何种原因您都不想向世界公开。假设您希望世界通过调用函数

来启动您的代码
start_magic();

然后,你要做的是:

  • 提供一个头文件:magic.h包含在main.c
  • 头文件将具有以下功能:void start_magic();
  • 然后将您的专有代码放在algo.c和algo.h
  • algo.c将有start_magic()实现
  • algo.c将包含专有的algo.h

现在您可以做的是编译(无链接)您的algo.c文件,并删除调试符号以使其难以进行逆向工程。如何完成取决于您使用的编译器。

现在,您可以将对象文件和头文件提供给想要调用函数start_magic()的人。

main的实现者必须使用您提供的目标文件链接程序。

示例

假设你的算法有algo.c。让我们说algo.c具有以下功能:

float sqrt(float x){ 
    taylor_approx(x); 
}

假设sqrt功能将与供应商共享。但是,sqrt函数调用专有函数taylor_approx(x)来计算平方根。

您可以创建一个algo.h文件发送给用户,其中包含:

extern float sqrt(float x);

然后你可以将调试符号编译的目标文件(例如algo.o)中的-stripped发送给用户,并要求他们将algo.h放在他们的main.c中。

请注意,这是一种方法。