从 PHP Web 应用程序调用 C++ 库:system() 与 SWIG PHP 扩展?
Posted
技术标签:
【中文标题】从 PHP Web 应用程序调用 C++ 库:system() 与 SWIG PHP 扩展?【英文标题】:Calling C++ library from PHP web app: system() vs SWIG PHP extension? 【发布时间】:2010-11-11 19:38:10 【问题描述】:我有一个 php Web 应用程序需要调用 C++ 库中的函数。该库由供应商提供(Linux 机器上的 libfoo.a)。
我的第一反应是创建一个链接 libfoo.a 的 C++ 可执行文件,并将命令行参数传递给函数。然后,PHP Web 应用程序可以对我的 c++ 可执行文件进行 system() 调用。这将很容易实现。我担心的是是否会为每次调用创建一个新的系统进程增加很多开销。这个开销是多少?
另一种方法是我可以使用 SWIG 将 C++ 函数包装在 PHP 扩展中,但我没有 C++ 源代码。 SWIG 是否支持与“.a”库链接?是否需要我团队中的所有其他工程师更改他们的 PHP 配置以在 libfoo.a 中构建?
如果 system() 调用的开销很小(
【问题讨论】:
你需要来自C++
的输出吗?如果不是,您可以考虑将呼叫推送到后台 - ***.com/questions/45953/…
只是一个简单的外部观察,但不知道它被调用的频率,听起来你最好制作一个 C++ 可执行文件(这将允许在 PHP 之外使用作为奖励) .如果你把它做成一个 PHP 扩展,我想你将不可避免地面临分发和兼容性维护的噩梦,即使对于一个小的私人用户群也是如此。自从您打开此问题后,您是否尝试过或发现了什么?
【参考方案1】:
请记住,C++ 与 C 会产生不同的函数名称修饰,因此具有相同外观的函数的不同 DLL 函数名称意味着不同的链接。
“第三方扩展提供程序必须重新构建其扩展,以使其与我们现在提供的 Visual Studio C++9 版本兼容和加载。”
【讨论】:
【参考方案2】:我建议使用一些 IPC(进程间通信)协议。如果您仍然要使用该库编写 C++ 应用程序 - 编写一些通信协议(使用 TCP/IP 或 unix 套接字)并将应用程序作为守护进程启动
见man 3 daemon
、man 2 fork
和Unix sockets guide
附:将库构建到 PHP 中并不是一个好主意 - C++ 不像 PHP 那样具有故障安全性。如果库或 php 模块崩溃 - 整个网络服务器崩溃,或者在最好的情况下,一个服务器进程崩溃。如果你将它分开并且程序/lib 崩溃了,你可以显示有问题的消息(甚至发送警报电子邮件),如果你的网络服务器关闭,这不会发生
【讨论】:
【参考方案3】:不知道你最后做了什么,但几年前我做了一个简单的 php 包装器扩展,调用了一个 C++ 库。像这样你不会有系统调用的开销。我对你来说不是问题,但你可以更好地控制对 lib 的调用。例如,将包装器加载到内存中,而不是在每次调用时加载它,保留自定义配置参数等。我取决于你的库的性质。
只是一些可能感兴趣的参考:
看看这个问题:Extending PHP with C++? 您提到了 Swig,但这里也是一个在 VS2005 上使用 Zend 的示例【讨论】:
【参考方案4】:我会推荐选项 2。我没有使用 PHP/SWIG 的经验,但对 perl、java 和 PLSQL (oracle) 做过同样的事情。我们将使用 C/C++ 编写一些核心功能(并使用第 3 方库),然后将其包装在适当的包装器中。
我们这样做主要是为了避免在三种应用程序语言中重复核心功能。使用 C 的效率是一个额外的好处。并且(在我看来)使用这样的包装器比使用系统“脱壳”更安全,因为您可以传递正确的参数和返回值作为变量,而不是解析标准输出的杂乱事务。
要记住的要点:
您需要使用应用程序语言(为您使用 PHP)提供的一些函数来为新数据分配任何内存。例如在 perl 的 NewSV 中。 通常需要一些配置来告诉 PHP 在哪里可以找到已编译的 .so/.dll【讨论】:
以上是关于从 PHP Web 应用程序调用 C++ 库:system() 与 SWIG PHP 扩展?的主要内容,如果未能解决你的问题,请参考以下文章
从 Node.js 调用 C++ 库(Node addons / node-ffi)
从 C++ 应用程序中的嵌入式 Python 调用时,多数组扩展库上的 Numpy 导入失败