[英]implicit declaration of function 'asprintf'
我创建了一个程序,可以帮助将我的 PHP 代码转换为可运行的 c 文件,因此我可以使用 PHP 函数。 该程序在我的系统(Windows 10)上完美运行,但无法在我同事的系统(Windows 10)上运行。 在我的 header 中,我创建了自己的 asprintf,因为 windows 上不存在 function。
我的 asprintf.h
#ifndef ASPRINTF_H
#define ASPRINTF_H
#if defined(__GNUC__) && ! defined(_GNU_SOURCE)
#define _GNU_SOURCE /* needed for (v)asprintf, affects '#include <stdio.h>' */
#endif
#include <stdio.h> /* needed for vsnprintf */
#include <stdlib.h> /* needed for malloc, free */
#include <stdarg.h> /* needed for va_* */
/*
* vscprintf:
* MSVC implements this as _vscprintf, thus we just 'symlink' it here
* GNU-C-compatible compilers do not implement this, thus we implement it here
*/
#ifdef _MSC_VER
#define vscprintf _vscprintf
#endif
#ifdef __GNUC__
int vscprintf(const char *format, va_list ap)
{
va_list ap_copy;
va_copy(ap_copy, ap);
int retval = vsnprintf(NULL, 0, format, ap_copy);
va_end(ap_copy);
return retval;
}
#endif
/*
* asprintf, vasprintf:
* MSVC does not implement these, thus we implement them here
* GNU-C-compatible compilers implement these with the same names, thus we
* don't have to do anything
*/
#ifdef _MSC_VER
int vasprintf(char **strp, const char *format, va_list ap)
{
int len = vscprintf(format, ap);
if (len == -1)
return -1;
char *str = (char*)malloc((size_t) len + 1);
if (!str)
return -1;
int retval = vsnprintf(str, len + 1, format, ap);
if (retval == -1) {
free(str);
return -1;
}
*strp = str;
return retval;
}
int asprintf(char **strp, const char *format, ...)
{
va_list ap;
va_start(ap, format);
int retval = vasprintf(strp, format, ap);
va_end(ap);
return retval;
}
#endif
#endif // ASPRINTF_H
我的主.c
#include "asprintf.h"
#include <stdio.h>
#include <stdlib.h>
extern char _binary_script_php_start;
extern char _binary_script_php_end;
int main(int argc, char *argv[]) {
// EXTRACT OUR RESOURCE OBJECT INTO /tmp/test.php
char *p = &_binary_script_php_start;
FILE *fp = fopen("/tmp/test.php","wb");
while ( p != &_binary_script_php_end ) {
fputc(*p++,fp);
}
fclose(fp);
// NOW READ IN OUR STANDARD ARGUMENTS AND LAUNCH OUR COMMAND
int i = 1;
char *cmd = "php /tmp/test.php";
char *s = NULL;
asprintf(&s, "%s",cmd);
for(i = 1; i < argc; i++) {
asprintf(&s, "%s \"%s\"",s,argv[i]);
}
// concatf("%s",cmd);
// for(i = 1; i < argc; i++) {
// concatf("%s \"%s\"",s,argv[i]);
// }
// concatf(&s, "%s",cmd);
// for(i = 1; i < argc; i++) {
// concatf(&s, "%s \"%s\"",s,argv[i]);
// }
system(s);
free(s);
unlink("/tmp/test.php"); // comment me out for debugging if you want
}
通过创建一个新的 header 文件并更改 function 的名称,我能够重新创建他们的错误。 所以当他们得到:
警告:隐含声明 function 'asprintf' [-Wimplicit-function-declaration] 29 | asprintf(&s, "%s",cmd);
我得到:
警告:隐含声明 function 'concatf' [-Wimplicit-function-declaration] 29 | concatf(&s, "%s",cmd);
这对我来说没有意义,我知道为了这个工作,function 应该在主要的 function 之前声明,这已经完成了。 我知道我必须定义在我的 header 文件中处理的 _GNU_SOURCE。 有没有我不遵守的规则? 如果是这样,为什么它会在我的环境而不是我的同事的环境中工作?
为了能够运行它,创建一个名为 script.php 的 PHP 文件并运行以下命令:
php:
ld -r -b binary script.php data.o
exe:
gcc main.c data.o -o runme
如果工作正常。/runme 应该运行 php 文件。
请在此处找到源代码: https://github.com/Sammiiie/C_php_http
这些标准可选的功能在文档中定义: ISO/IEC TR 24731-2 。
在包含 header stdio.h
之前,需要明确启用它们来定义常量__STDC_WANT_LIB_EXT2__
。
来自ISO/IEC TR 24731-2,5.1.1标准标题:
如果_STDC_WANT_LIB_EXT2_被定义为在源文件中包含适当Z099FB995346F31C743F6E40DB0F39的点处扩展为integer常量1的宏,则第5条及其子条款中定义的函数、宏和类型由它们各自的头文件定义。
IE
#define __STDC_WANT_LIB_EXT2__ 1
#include <stdio.h>
....
在您的情况下,要仅为非 MS 编译器启用它,您可以编写:
#ifndef _MSC_VER
#define __STDC_WANT_LIB_EXT2__ 1
#endif
#include <stdio.h>
....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.