呼叫 C++ PHP Web 应用程序中的库:system() 与 SWIG PHP 扩展?
我有一个 PHP Web 应用程序,需要调用 C++ 库中的函数。该库由供应商提供(Linux 机器上为 libfoo.a)。
我的第一反应是创建一个链接 libfoo.a 的 C++ 可执行文件,并将命令行参数传递给该函数。然后,PHP Web 应用程序可以对我的 C++ 可执行文件执行 system() 调用。这很容易实现。我担心的是,为每个调用创建一个新的系统进程是否会增加大量开销。这个开销是多少?
另一种方法是我可以使用 SWIG 将 C++ 函数包装在 PHP 扩展中,但我没有 C++ 源代码。 SWIG 是否支持与“.a”库链接?是否需要我团队中的所有其他工程师更改他们的 PHP 配置以在 libfoo.a 中构建?
如果 system() 调用的开销很小(< 30 ms),我更喜欢选项 #1,因为创建 C++ 可执行文件一次而不是将其构建到 PHP 应用程序中似乎要简单得多。您对这两个选项有何建议?
I have a PHP web application that needs to call a function in a C++ library. This library is provided by a vendor (libfoo.a on a linux machine).
My first instinct is to create a C++ executable that links against libfoo.a, and passes command-line parameters to the function. The PHP web application can then do a system() call to my c++ executable. This would be easy to implement. My concern is whether it would add a lot of overhead to create a new system process for each call. How much would this overhead be?
An alternative is that I could use SWIG to wrap the C++ function in a PHP extension, but I don't have the C++ source code. Does SWIG support linking with a ".a" library? Would it require every other engineer on my team to change their PHP configuration to build in libfoo.a?
If the overhead of the system() call is small (< 30 ms), I would prefer option #1, as it seems much simpler to create the C++ executable once, and not build it into the PHP application. What are your recommendations on the two options?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请记住,C++ 与 C 会产生不同的函数名称重整,因此具有相同外观的函数的不同 DLL 函数名称意味着不同的链接。
“第三方扩展提供商必须重建其扩展,以使它们与我们现在提供的 Visual Studio C++9 版本兼容并可加载。”
keep in mind that C++ vs C produces different function name mangling thus different DLL function names with the same-looking functions which means different linkage.
"Third party extension providers must rebuild their extensions to make them compatible and loadable with the Visual Studio C++9 builds that we now provide."
我建议使用一些 IPC(进程间通信)协议。如果您要使用该库编写 C++ 应用程序 - 编写一些通信协议(使用 TCP/IP 或 unix 套接字)并将应用程序作为守护进程启动,
请参阅
man 3 daemon
、man 2 fork
和 Unix 套接字指南PS 构建库进入 PHP 并不是一个好主意 - C++ 并不像 PHP 那样安全。如果库或 php 模块崩溃 - 整个网络服务器崩溃,或者在最好的情况下,一个服务器进程崩溃。如果将其分开并且程序/库崩溃,您可以显示出现问题的消息(甚至发送警报电子邮件),如果您的 Web 服务器关闭,则不会发生这种情况
I would suggest using some IPC (inter process communication) protocol. If you are gonna write the C++ application using the library anyway - write some communication protocol (using TCP/IP or unix sockets) and start the application as a daemon
see
man 3 daemon
,man 2 fork
and Unix sockets guideP.S. building the library into PHP is not a good idea - C++ is not that failsafe like PHP. if the library or php module crashes - the whole webserver crashes or in the best scenario the one server process crashes. If you separate it and the program/lib crashes, you can show message that something is wrong (or even send alert email), which can't happen if your web server is down
不确定你最后做了什么,但几年前我已经做了一个简单的 php 包装扩展 调用 C++ 库。这样你就不会产生系统调用的开销。我对你来说不是问题,但你可以更好地控制对库的调用。例如,将包装器加载在内存中,而不是在每次调用时加载它,保留自定义配置参数等。我取决于您的库的性质。
只是一些可能感兴趣的参考:
Not sure what you did finally but I've done a simple php wrapper extension years ago calling a C++ lib. Like this you will not have overhead of a system call. I'ts not an issue for you, but you'll have finer control over calls to the lib. For example keeping the wrapper loaded in memory as opposed to loading it on each call, keeping custom configuration parameters etc. I depends on the nature of your lib.
Just some references that might be of interest:
我推荐选项 2。我没有 PHP/SWIG 的经验,但对 perl、java 和 PLSQL (oracle) 做过同样的事情。我们将用一些 C/C++ 代码(并使用第 3 方库)编写一些核心功能,然后将其包装在适当的包装器中。
我们这样做主要是为了避免在三种应用程序语言中重复核心功能。使用 C 语言的效率是一个额外的好处。 (在我看来)使用这样的包装器比用系统“剔除”更安全,因为您可以传递适当的参数并返回值作为变量,而不是解析标准输出的混乱业务。
要记住的要点:
I would recommend option 2. I do not have experience with PHP/SWIG but have done the same thing for perl, java, and PLSQL (oracle). We'll code some core functionality in a bit of C/C++ (and use 3rd party libraires) which we then wrap in an appropriate wrapper.
We do this mainly so we don't have duplicate the core functionality in the three application languages. The efficiency of using C is an added benefit. And Using a wrapper like this is (in my opinion) safer than than "shelling out" with system because you can pass proper parameters and return values as variables opposed to the messy business of parsing standard output.
Main points to remember: