繁体   English   中英

function 'asprintf' 的隐式声明

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM