C 编译libPNG示例时未定义的引用

C 编译libPNG示例时未定义的引用,c,libpng,C,Libpng,我尝试了libPNG示例,但在编译时失败了。我使用了gcc-lm-lpng makePNG.c来编译它,得到了以下错误: /tmp/ccgGO8zw.o: In function `writeImage': makePNG.c:(.text+0x360): undefined reference to `setRGB' collect2: error: ld returned 1 exit status 我删除了函数定义,只是简单地移动了函数,使它们按以下顺序排列: void setRGB(p

我尝试了libPNG示例,但在编译时失败了。我使用了
gcc-lm-lpng makePNG.c
来编译它,得到了以下错误:

/tmp/ccgGO8zw.o: In function `writeImage':
makePNG.c:(.text+0x360): undefined reference to `setRGB'
collect2: error: ld returned 1 exit status
我删除了函数定义,只是简单地移动了函数,使它们按以下顺序排列:

void setRGB(png_byte *ptr, float val)
int writeImage(char* filename, int width, int height, float *buffer, char* title)
float *createMandelbrotImage(int width, int height, float xS, float yS, float rad, int maxIteration)
int main(int argc, char *argv[])
它成功了。我的问题是:为什么它以前不起作用?SetRGB是在writeImage之前定义的,那么“SetRGB”引用怎么可能是未定义的呢

编辑:


我忘了提一些我现在意识到非常重要的事情。我从setRGB函数中删除了'inline'关键字。我试着用内联关键字编译,它有相同的错误消息。因此,很明显,我的问题与内联关键字有关,而不是像我最初认为的那样,与转发声明有关…

多亏了David C.Rankin,我找到了一个可以编译此命令的命令
gcc-Ofast-lm-lpng makePNG.c之所以有效,是因为它包含了-Ofast选项。这是
man gcc
中对该选项的描述:

-过去

无视严格的标准遵从性

-Ofast支持所有O3优化。它还支持对所有标准兼容程序无效的优化。它打开了 -ffast数学和Fortran特有的-fno保护parens和-fstack数组

我怀疑作者使用内联的方式不符合c规范,这就是为什么没有这个选项它无法编译。不用说,编写不符合c标准的代码是绝对不合适的

编辑:

证明-Ofast选项是罪魁祸首的证据:

$ gcc -Ofast -lm -lpng makePNG.c
$ gcc -lm -lpng makePNG.c
/tmp/cc2JlymP.o: In function `writeImage':
makePNG.c:(.text+0x360): undefined reference to `setRGB'
collect2: error: ld returned 1 exit status
$ 

示例编译和构建很好,请参见Try
gcc-Wall-Wextra-pedantic-std=gnu11-Ofast-o libpngex libpngex.c-lm-lpng
,然后运行
/libpngex output.png
inline
关键字只是编译器的一个“提示”,表明它可以内联函数。不能保证它能做到。但是,函数声明和函数定义之间必须保持一致。你不能在其中一个上有
inline
,而在另一个上没有,它们将被视为两个不同的函数。我的源代码名是
libpngex.c
。只需使用你的
makePNG
,例如
gcc-Wall-Wextra-pedantic-std=gnu11-Ofast-o makePNG-lm-lpng makePNG.c
,然后运行
/makePNG somepng.png
你发布的是
gcc-Wall-Wextra-pedantic-std=gnu11-Ofast-o libpngex makePNG.c-lm-lpng.c
。去掉其中一个
makePNG.c
,您的输出将在
libpngex
中,或者去掉
libpngex
,并从第一个
makePNG.c
中删除
.c'
。如果仔细查看发布的命令
gcc-Wall-Wextra-pedantic-std=gnu11-Ofast-o libpngex-makePNG.c-lm-lpng>makePNG.c
您包含了两次
makePNG.c
。这就是导致
“code”可能被删除的原因…
警告。实际问题在于使用
setjmp(png_jmpbuf(png_ptr))
。查看
手册页中的最后一句话“
setjmp()
sigsetjmp()
使程序难以理解和维护。如果可能,应使用替代方法。”此代码将使用
-O2
或更高优化进行干净编译。在
libpng12
中对
libpng
进行了更改,之后隐藏了实际的
png
结构成员,这些成员需要使用
png_jmpbuf
。您是对的,它甚至可以在我的机器上使用-O优化。