C 函数 pow() 不会在共享主机服务器中执行
C function pow() won't execute in shared hosting server
我正在尝试通过 PHP exec() 函数 运行 一个 C 程序。在我的本地主机上一切 运行 都很好,但是当 运行 在托管服务器上将它连接时,带有 pow() 函数并以变量作为参数的 C 程序将不会执行。
我问了那个主机的客服,他们说他们的服务器不支持执行C编程语言。
但令我感到奇怪的是,为什么我的另一个 C 程序 运行 在那台服务器上运行良好,只是其中一个包含变量作为参数的 pow() 的代码不会' t 运行.
这是我的代码:
PHP
public function index() {
//runs well
$varExec = exec(app_path() . "/Exec/checkfuncpow.exe");
var_dump($varExec);
echo "<br/>";
//this the one that is not running
$varExec = exec(app_path() . "/Exec/checkfuncpowwithvar.exe");
var_dump($varExec);
}
结果:
字符串(8)“9.000000”
字符串(0)“”
checkfuncpow.c
#include <stdio.h>
#include <math.h>
int main() {
printf("%f", pow((double)3, (double)2));
return 0;
}
checkfuncpowwithvar.c
#include <stdio.h>
#include <math.h>
int main() {
double param = 3;
printf("%f", pow(param, (double)2));
return 0;
}
两个代码都使用强制性 -lm 标志编译为 link 到数学库
gcc checkfuncpow.c -o ./Exec/checkfuncpow.exe -lm
gcc checkfuncpowwithvar.c -o ./Exec/checkfuncpowwithvar.exe -lm
那么最终的问题是,真的是因为服务器不支持吗?或者它应该能够 运行 但客户支持没有关于这个问题的线索,所以他们只是说什么对他们来说很容易?
标准答案:如果您的托管服务不支持执行 C 程序,那么您不应该这样做;首先,因为程序可能有错误或奇怪的行为(如本例),其次,因为托管服务不会在出现问题时为您提供任何支持(如本例)。
有趣的答案:这里经历的谜团可能与两件事有关:1)编译器优化; 2) 缺少数学库。
关于编译器优化,您的两个程序恰好表现不同,因为在第一种情况下(没有 param
变量),编译器将 pow((double)3, (double)2)
替换为 (double) 9.0
;因此没有调用 pow()
,也不需要数学库。在第二种情况下,编译器没有优化 pow()
调用,所以数学库仍然是必要的。如果我的猜测是正确的,并且你用 gcc 选项 -O3
编译你的两个程序,现在两个程序应该 运行 没有问题。
关于缺少数学库:数学库动态地linked到您的程序中(使用-lm
选项);这意味着程序 运行 所在的目标平台需要安装该库。另一方面,静态 linked 库嵌入到您的程序中,因此目标平台不需要安装它们。
您可以尝试的一件事是静态 link 数学库 (libm
)。不知道怎么操作就搜索主题
编辑:为了静态解决问题-link将库放入您的可执行文件中,您可以查看this Whosebug question。 TL;DR:只要库的静态版本可用,GCC 选项 -static
应该告诉编译器使用静态库而不是动态库。在libm
的情况下,在我的Ubuntu 20.04盒子上,libm
的静态版本可用,所以如果我用命令gcc -o program main.c -lm -static
编译程序,GCC成功使用静态版本libm
.
我正在尝试通过 PHP exec() 函数 运行 一个 C 程序。在我的本地主机上一切 运行 都很好,但是当 运行 在托管服务器上将它连接时,带有 pow() 函数并以变量作为参数的 C 程序将不会执行。
我问了那个主机的客服,他们说他们的服务器不支持执行C编程语言。
但令我感到奇怪的是,为什么我的另一个 C 程序 运行 在那台服务器上运行良好,只是其中一个包含变量作为参数的 pow() 的代码不会' t 运行.
这是我的代码:
PHP
public function index() {
//runs well
$varExec = exec(app_path() . "/Exec/checkfuncpow.exe");
var_dump($varExec);
echo "<br/>";
//this the one that is not running
$varExec = exec(app_path() . "/Exec/checkfuncpowwithvar.exe");
var_dump($varExec);
}
结果:
字符串(8)“9.000000”
字符串(0)“”
checkfuncpow.c
#include <stdio.h>
#include <math.h>
int main() {
printf("%f", pow((double)3, (double)2));
return 0;
}
checkfuncpowwithvar.c
#include <stdio.h>
#include <math.h>
int main() {
double param = 3;
printf("%f", pow(param, (double)2));
return 0;
}
两个代码都使用强制性 -lm 标志编译为 link 到数学库
gcc checkfuncpow.c -o ./Exec/checkfuncpow.exe -lm
gcc checkfuncpowwithvar.c -o ./Exec/checkfuncpowwithvar.exe -lm
那么最终的问题是,真的是因为服务器不支持吗?或者它应该能够 运行 但客户支持没有关于这个问题的线索,所以他们只是说什么对他们来说很容易?
标准答案:如果您的托管服务不支持执行 C 程序,那么您不应该这样做;首先,因为程序可能有错误或奇怪的行为(如本例),其次,因为托管服务不会在出现问题时为您提供任何支持(如本例)。
有趣的答案:这里经历的谜团可能与两件事有关:1)编译器优化; 2) 缺少数学库。
关于编译器优化,您的两个程序恰好表现不同,因为在第一种情况下(没有 param
变量),编译器将 pow((double)3, (double)2)
替换为 (double) 9.0
;因此没有调用 pow()
,也不需要数学库。在第二种情况下,编译器没有优化 pow()
调用,所以数学库仍然是必要的。如果我的猜测是正确的,并且你用 gcc 选项 -O3
编译你的两个程序,现在两个程序应该 运行 没有问题。
关于缺少数学库:数学库动态地linked到您的程序中(使用-lm
选项);这意味着程序 运行 所在的目标平台需要安装该库。另一方面,静态 linked 库嵌入到您的程序中,因此目标平台不需要安装它们。
您可以尝试的一件事是静态 link 数学库 (libm
)。不知道怎么操作就搜索主题
编辑:为了静态解决问题-link将库放入您的可执行文件中,您可以查看this Whosebug question。 TL;DR:只要库的静态版本可用,GCC 选项 -static
应该告诉编译器使用静态库而不是动态库。在libm
的情况下,在我的Ubuntu 20.04盒子上,libm
的静态版本可用,所以如果我用命令gcc -o program main.c -lm -static
编译程序,GCC成功使用静态版本libm
.