如何在c中隐藏公共API中的帮助函数
Posted
技术标签:
【中文标题】如何在c中隐藏公共API中的帮助函数【英文标题】:How to hide helper functions from public API in c 【发布时间】:2011-03-02 06:51:30 【问题描述】:我正在处理一个项目,我需要创建一个 API。我正在使用套接字在服务器(我的应用程序)和客户端(使用我的 API 的其他应用程序)之间进行通信。
这个项目是c而不是C++
我来自 linux 背景,这是我第一个使用 Windows、Visual Studio 2008 和 dll 库的项目。
我在客户端和服务器之间进行通信,但我有一些在两个项目中重复。我想创建一个库(可能是一个 dll 文件),这两个项目都可以链接到,所以我不必维护额外的代码。
我还必须创建包含我需要为我的客户提供的 API 的库。在我希望公开的 API 函数中,是对这些“重复代码”的辅助函数的调用,我不想将这些函数公开给我的客户端,但我确实希望我的服务器能够使用这些函数。我该怎么做?
我将尝试用一个例子来澄清。这是我开始的。
服务器项目:
int Server_GetPacket(SOCKET sd);
int ReceiveAll(SOCKET sd, char *buf, int len);
int VerifyLen(char *buf);
客户项目:
int Client_SendCommand(int command);
int Client_GetData(int command, char *buf, int len);
int ReceiveAll(SOCKET sd, char *buf, int len);
int VerifyLen(char *buf);
这就是我想要的结果:
//Server Project:
int Server_GetPacket(SOCKET sd);
// library with public and private types
// private API (not exposed to my client)
int ReceiveAll(SOCKET sd, char *buf, int len);
int VerifyLen(char *buf);
// public API (header file available for client)
int Client_SendCommand(int command);
int Client_GetData(int command, char *buf, int len);
感谢任何帮助。
【问题讨论】:
【参考方案1】:如果您只想在 DLL 中公开某些函数,您可以创建一个导出文件 (dllname.def),在构建项目时将其提供给链接器。此导出文件包含您希望使用您的 DLL 的应用程序公开可用的函数列表。
有关这方面的更多信息,请参阅 MSDN 文章 here。
我认为您也可以通过在要导出的函数上使用__declspec(dllexport)
关键字来实现类似的功能。
【讨论】:
【参考方案2】:如果您将“私有”函数放在 DLL 中并使其可通过正常方式在外部调用(例如,可由加载库的进程调用),那么它们对于其他人也将是“公共的”。可以混淆名称和类似的东西,但这可能不是一个好的解决方案。
将它们放入静态链接库而不是 DLL 可能会更好。但请注意,即使在这种情况下,也有人可以明显地反汇编二进制文件并获取代码。
【讨论】:
我更关心的是提供一个只包含公共函数的干净 API。我只是想避免让所有辅助函数成为 API 的一部分。你是说我为“私有”函数创建一个静态库,然后将“公共 API”函数放入 DLL 中? @emge:这是一种可能性。这是否有意义取决于您的开发架构。 “更简单”的解决方案是简单地将源文件包含在项目中并将它们直接构建到二进制文件中。然后将公共 API DLL 构建为具有所需导出函数的单独项目。 谢谢,我喜欢“更简单”的解决方案,但是如果我只在项目中包含源文件并且 API DLL 需要使用其中的一些,我该如何解决重复代码的问题功能一样吗? @emge:我可能不理解这个问题。但是您不能将共享代码放在 sharedcode.c 之类的文件中,然后在客户端和服务器项目中都包含该文件(或根据需要包含多个文件)吗?然后代码被内置到两个项目中,但我不认为这违反了 DRY 规则。 好的,谢谢,我将尝试创建一个 common.c 文件,看看是否可以让一切正常工作。什么是 DRY 规则?【参考方案3】:使用
static int ReceiveAll(SOCKET sd, char *buf, int len);
etc 使函数本地化到文件/编译单元。
【讨论】:
如果我将私有函数声明为静态并将它们放入库中,我是否可以从我的服务器项目(即从 Server_GetPacket() 中)调用它? 同一个文件中的函数会看到它们。其他人不会。以上是关于如何在c中隐藏公共API中的帮助函数的主要内容,如果未能解决你的问题,请参考以下文章
如何在 API 中隐藏迭代器以使用 std::map 包装器中的项目
如何在 C# Rest API 中处理查询参数中的可选 ENUM - 无效和空值以及在 Swagger 中隐藏特定值
如何使用 ProGuard(或任何其他方式)隐藏库 Jar 中的公共类?