假设正在开发的应用程序需要某些功能,这些功能既可以通过对命令行程序进行系统调用来实现,也可以利用库来实现。假设效率不是一个问题,那么只是通过对程序进行系统调用来实现,而不是利用库,这是一个不好的做法吗?这样做的缺点是什么?
为了让事情更具体化,这种情况的一个例子是一个应用程序需要从Web服务器下载文件,可以使用cURL程序或libcURL库。
假设正在开发的应用程序需要某些功能,这些功能既可以通过对命令行程序进行系统调用来实现,也可以利用库来实现。假设效率不是一个问题,那么只是通过对程序进行系统调用来实现,而不是利用库,这是一个不好的做法吗?这样做的缺点是什么?
为了让事情更具体化,这种情况的一个例子是一个应用程序需要从Web服务器下载文件,可以使用cURL程序或libcURL库。
Unless you are writing code for only one OS, there is no way of knowing if your system call will even work. What happens when there is a system update or an OS upgrade?
Never use a system call if there is a library to do the same function.
我更喜欢使用库,因为存在依赖问题,也就是说,当您调用可执行文件时,它可能不存在,但是库一定存在(假设在您的平台上启动进程时已经处理好了外部库引用)。换句话说,与使用系统调用相比,使用库似乎可以在更多的环境中保证更稳定、可预测的结果。
有几个因素要考虑。 其中一个关键因素是外部程序是否可靠,并在安装您的软件的所有系统上存在。 如果有可能会丢失,那么最好在程序内部完成。
与此相比,您可能要考虑到额外的代码加载使您的程序不堪重负 - 对于应用程序中很少使用的部分,您不需要代码膨胀。
system()函数方便,但危险,尤其是因为它通常会调用shell。您最好直接调用程序-在Unix系统中,通过fork()和exec()系统调用。[请注意,系统调用与调用system()函数非常不同!]另一方面,您可能需要担心确保您程序中的所有打开文件描述符都已关闭-特别是如果您的程序是代表其他用户运行的某种守护程序;如果您没有使用特权,则此问题就不重要,但最好不要让调用的程序访问任何您没有打算访问的内容。您可能需要查看fcntl()系统调用和FD_CLOEXEC标志。
通常情况下,如果将功能集成到程序中则更容易控制事物,但这不是一个微不足道的决定。
安全是一个问题。一个恶意的cURL可能会在你的程序中造成混乱。这取决于这是否是一个以编码速度为主要关注点的个人程序,还是一个像安全这样的因素对商业应用程序起作用。
系统调用更难以安全地进行。
各种有趣的字符需要正确编码以传递参数,并且编码的类型可能会因平台或命令版本而异。因此,进行包含任何用户数据的系统调用需要进行大量的健全性检查,很容易犯错。
是的,如上所述,请铭记系统调用(例如fcntl()和open())与system()调用之间的区别。 :)
在原型设计C程序的早期阶段,我经常使用popen()对文件进行grep和sed等程序的外部调用以进行操作。这不安全,不安全也不可移植。但它可以让您快速上手。这对我很有价值。它让我专注于程序的真正核心,通常是我最初选择使用C的原因。
在高级编程语言中,你最好有一个非常好的理由。 :)
与其做任何一个,我会使用Unix并构建一个脚本框架,根据命令行参数和stdin来处理你的应用。
其他人已经提到了好的观点(可靠性、安全性、安全性、可携带性等),但是我想再提一个观点。性能。通常来说,调用库函数甚至生成一个新线程比启动一个完整的新进程要快得多(然后你还必须正确地检查/验证它的执行并解析它的输出!)。