关于静态库和共享库的C题
C questions about static and shared libraries
我有一些 .c 和 .h 文件,主要功能封装在 MAIN_FUNC.c 中。我需要将它们传递给要将 MAIN_FUNC()
与其文件集成的人。
然而,由于我的算法是机密的,我不能只发送 .c 和 .h 文件,所以我一直查看静态库和共享库。不过我还是有些疑惑。
1: 在我见过的每个教程中,也需要 .h。有什么方法可以让他只发送一个库文件,他可以在他的代码中 #include
吗?
2: 即使我必须传递 .hs 个文件,我真的需要传递所有这些文件吗?我怎样才能只给他libMAIN_FUNC.a和MAIN_FUNC.h?
3: 使用 .a 或 .so 库,有什么办法对文件进行逆向工程,以便可以看到 .c 和 .h 代码?
1) 您可以将 C
文件编译成库(*.a
或其他),前提是它已正确编写并与 h
文件一起分发。你必须提供 h
文件,因为它们是你的库的接口,否则它只是一个二进制 blob。
2) 您需要通过 headers 声明您的库正在导出的 public 接口。 IE。您希望库的用户可以访问的函数和符号。
3) 是的,总有办法对任何东西进行逆向工程。唯一的问题是 gain/effort 比率。
- 不行,你至少要给他提供一个.h文件。
- 不,您只需要传递那些足以定义您的图书馆和用户之间的接口的文件。我建议你阅读 pimpl 范式
- 理论上是的,您的 .a 和 .so 文件可以进行逆向工程,但这非常重要。
首先,关于逆向工程。给定无限的时间和资源,您的代码总是可以被逆向工程。话虽如此,您的 objective 会让其他人无法对您的代码进行逆向工程。
现在回答你的问题:
从 C 代码生成可执行二进制文件需要 "two major" 个步骤。编译和链接。
编译后,你的 files.c 变成目标文件(机器代码)。它们还不可执行。
如果您有两个文件:file1.c 和 file2.c,例如您将得到 file1.o 和 file2.o。
现在,file1.c 中的代码可能正在调用 file2.o 中存在的函数。在编译阶段,file1.c只需要知道函数原型即可。
当调用 linker 生成可执行二进制文件时,它确保从 file1.o 调用的函数存在于某处,例如 file2.o.
这对您有何影响:
头文件不应该是专有的(但也许是出于法律原因)。头文件主要用于告诉其他 .c 文件需要什么函数和 return 值(声明,而不是实现)。
现在,也许您出于某种原因不想向世界公开某些专有函数原型。假设您希望世界通过调用函数
来启动您的代码
start_magic();
那么,你要做的是:
- 提供一个头文件:magic.h要包含在main.c
- 头文件将具有函数:void start_magic();
- 然后您将专有代码放入 algo.c 和 algo.h
- algo.c 将有 start_magic() 实现
- algo.c 将包括专有 algo.h
现在你可以做的是编译(没有 linking)你的 algo.c 文件,并去除调试符号以使其难以逆向工程。具体如何完成取决于您使用的编译器。
现在您可以将目标文件和头文件提供给想要调用函数 start_magic() 的人。
main 的实现者必须 link 使用您提供的目标文件的程序。
例子
假设您的算法有 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,发送给用户并要求他们将 algo.h 放入他们的 main.c
请注意,这是一种方法。
我的理解是,您有一个 .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 文件。您只需要提供有关函数功能的知识(即 "This function takes an input from the console and returns the number of words written as an integer")——一些基本的知识,可以在不泄露源代码的情况下实现您的工作。
编辑:修正了一个拼写错误
我有一些 .c 和 .h 文件,主要功能封装在 MAIN_FUNC.c 中。我需要将它们传递给要将 MAIN_FUNC()
与其文件集成的人。
然而,由于我的算法是机密的,我不能只发送 .c 和 .h 文件,所以我一直查看静态库和共享库。不过我还是有些疑惑。
1: 在我见过的每个教程中,也需要 .h。有什么方法可以让他只发送一个库文件,他可以在他的代码中 #include
吗?
2: 即使我必须传递 .hs 个文件,我真的需要传递所有这些文件吗?我怎样才能只给他libMAIN_FUNC.a和MAIN_FUNC.h?
3: 使用 .a 或 .so 库,有什么办法对文件进行逆向工程,以便可以看到 .c 和 .h 代码?
1) 您可以将 C
文件编译成库(*.a
或其他),前提是它已正确编写并与 h
文件一起分发。你必须提供 h
文件,因为它们是你的库的接口,否则它只是一个二进制 blob。
2) 您需要通过 headers 声明您的库正在导出的 public 接口。 IE。您希望库的用户可以访问的函数和符号。
3) 是的,总有办法对任何东西进行逆向工程。唯一的问题是 gain/effort 比率。
- 不行,你至少要给他提供一个.h文件。
- 不,您只需要传递那些足以定义您的图书馆和用户之间的接口的文件。我建议你阅读 pimpl 范式
- 理论上是的,您的 .a 和 .so 文件可以进行逆向工程,但这非常重要。
首先,关于逆向工程。给定无限的时间和资源,您的代码总是可以被逆向工程。话虽如此,您的 objective 会让其他人无法对您的代码进行逆向工程。
现在回答你的问题: 从 C 代码生成可执行二进制文件需要 "two major" 个步骤。编译和链接。 编译后,你的 files.c 变成目标文件(机器代码)。它们还不可执行。
如果您有两个文件:file1.c 和 file2.c,例如您将得到 file1.o 和 file2.o。
现在,file1.c 中的代码可能正在调用 file2.o 中存在的函数。在编译阶段,file1.c只需要知道函数原型即可。
当调用 linker 生成可执行二进制文件时,它确保从 file1.o 调用的函数存在于某处,例如 file2.o.
这对您有何影响:
头文件不应该是专有的(但也许是出于法律原因)。头文件主要用于告诉其他 .c 文件需要什么函数和 return 值(声明,而不是实现)。
现在,也许您出于某种原因不想向世界公开某些专有函数原型。假设您希望世界通过调用函数
来启动您的代码start_magic();
那么,你要做的是:
- 提供一个头文件:magic.h要包含在main.c
- 头文件将具有函数:void start_magic();
- 然后您将专有代码放入 algo.c 和 algo.h
- algo.c 将有 start_magic() 实现
- algo.c 将包括专有 algo.h
现在你可以做的是编译(没有 linking)你的 algo.c 文件,并去除调试符号以使其难以逆向工程。具体如何完成取决于您使用的编译器。
现在您可以将目标文件和头文件提供给想要调用函数 start_magic() 的人。
main 的实现者必须 link 使用您提供的目标文件的程序。
例子
假设您的算法有 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,发送给用户并要求他们将 algo.h 放入他们的 main.c
请注意,这是一种方法。
我的理解是,您有一个 .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 文件。您只需要提供有关函数功能的知识(即 "This function takes an input from the console and returns the number of words written as an integer")——一些基本的知识,可以在不泄露源代码的情况下实现您的工作。
编辑:修正了一个拼写错误