我有一些 .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 代码?
答案 0 :(得分:2)
答案 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();
然后,你要做的是:
现在您可以做的是编译(无链接)您的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中。
请注意,这是一种方法。