При компиляции вылетает указанная ниже ошибка. В чем может быть проблем? Linux
Часть кода
в шапке
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pulse/simple.h>
#include <pulse/error.h>
static const pa_sample_spec ss = {
.format = PA_SAMPLE_ULAW,
.rate = 8000,
.channels = 1
};
pa_simple *s_in, *s_out = NULL;
int ret = 1;
int error;
/* Create a new playback stream */
if (!(s_out = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %sn", strerror(errno));
goto finish;
}
if (!(s_in = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %sn", strerror(errno));
goto finish;
}
for (;;) {
uint8_t buf[BUFSIZE];
ssize_t r;
if (pa_simple_read(s_in, buf, sizeof(buf), &error) < 0) {
fprintf(stderr, __FILE__": read() failed: %sn", strerror(errno));
goto finish;
}
if(write(fd, buf, BUFSIZE) != BUFSIZE)
printf("nErrn");
if(write(fd, audio, 7) != 7)
printf("nErrn");*/
if (pa_simple_write(s_out, buf, sizeof(buf), &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_write() failed: %sn", strerror(errno));
goto finish;
}
}
/* Make sure that every single sample was played */
if (pa_simple_drain(s_out, &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_drain() failed: %sn", strerror(errno));
goto finish;
}
ret = 0;
finish:
if(fd){
shutdown(fd, SHUT_RDWR);
close(fd);
}
if (s_in)
pa_simple_free(s_in);
if (s_out)
pa_simple_free(s_out);
return ret;
}
Ошибка
cgiplay_AudioOut_HTTP.cpp:(.text+0x22b): undefined reference to `pa_simple_new'
cgiplay_AudioOut_HTTP.cpp:(.text+0x2b5): undefined reference to `pa_simple_new'
cgiplay_AudioOut_HTTP.cpp:(.text+0x325): undefined reference to `pa_simple_read'
cgiplay_AudioOut_HTTP.cpp:(.text+0x3ea): undefined reference to `pa_simple_write'
cgiplay_AudioOut_HTTP.cpp:(.text+0x463): undefined reference to `pa_simple_free'
cgiplay_AudioOut_HTTP.cpp:(.text+0x47c): undefined reference to `pa_simple_free'
collect2: error: ld returned 1 exit status
Your linkage consumes libraries before the object files that refer to them
- You are trying to compile and link your program with the GCC toolchain.
- Your linkage specifies all of the necessary libraries and library search paths
- If
libfoo
depends onlibbar
, then your linkage correctly putslibfoo
beforelibbar
. - Your linkage fails with
undefined reference to
something errors. - But all the undefined somethings are declared in the header files you have
#include
d and are in fact defined in the libraries that you are linking.
Examples are in C. They could equally well be C++
A minimal example involving a static library you built yourself
my_lib.c
#include "my_lib.h"
#include <stdio.h>
void hw(void)
{
puts("Hello World");
}
my_lib.h
#ifndef MY_LIB_H
#define MT_LIB_H
extern void hw(void);
#endif
eg1.c
#include <my_lib.h>
int main()
{
hw();
return 0;
}
You build your static library:
$ gcc -c -o my_lib.o my_lib.c
$ ar rcs libmy_lib.a my_lib.o
You compile your program:
$ gcc -I. -c -o eg1.o eg1.c
You try to link it with libmy_lib.a
and fail:
$ gcc -o eg1 -L. -lmy_lib eg1.o
eg1.o: In function `main':
eg1.c:(.text+0x5): undefined reference to `hw'
collect2: error: ld returned 1 exit status
The same result if you compile and link in one step, like:
$ gcc -o eg1 -I. -L. -lmy_lib eg1.c
/tmp/ccQk1tvs.o: In function `main':
eg1.c:(.text+0x5): undefined reference to `hw'
collect2: error: ld returned 1 exit status
A minimal example involving a shared system library, the compression library libz
eg2.c
#include <zlib.h>
#include <stdio.h>
int main()
{
printf("%sn",zlibVersion());
return 0;
}
Compile your program:
$ gcc -c -o eg2.o eg2.c
Try to link your program with libz
and fail:
$ gcc -o eg2 -lz eg2.o
eg2.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status
Same if you compile and link in one go:
$ gcc -o eg2 -I. -lz eg2.c
/tmp/ccxCiGn7.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status
And a variation on example 2 involving pkg-config
:
$ gcc -o eg2 $(pkg-config --libs zlib) eg2.o
eg2.o: In function `main':
eg2.c:(.text+0x5): undefined reference to `zlibVersion'
What are you doing wrong?
In the sequence of object files and libraries you want to link to make your
program, you are placing the libraries before the object files that refer to
them. You need to place the libraries after the object files that refer
to them.
Link example 1 correctly:
$ gcc -o eg1 eg1.o -L. -lmy_lib
Success:
$ ./eg1
Hello World
Link example 2 correctly:
$ gcc -o eg2 eg2.o -lz
Success:
$ ./eg2
1.2.8
Link the example 2 pkg-config
variation correctly:
$ gcc -o eg2 eg2.o $(pkg-config --libs zlib)
$ ./eg2
1.2.8
The explanation
Reading is optional from here on.
By default, a linkage command generated by GCC, on your distro,
consumes the files in the linkage from left to right in
commandline sequence. When it finds that a file refers to something
and does not contain a definition for it, to will search for a definition
in files further to the right. If it eventually finds a definition, the
reference is resolved. If any references remain unresolved at the end,
the linkage fails: the linker does not search backwards.
First, example 1, with static library my_lib.a
A static library is an indexed archive of object files. When the linker
finds -lmy_lib
in the linkage sequence and figures out that this refers
to the static library ./libmy_lib.a
, it wants to know whether your program
needs any of the object files in libmy_lib.a
.
There is only object file in libmy_lib.a
, namely my_lib.o
, and there’s only one thing defined
in my_lib.o
, namely the function hw
.
The linker will decide that your program needs my_lib.o
if and only if it already knows that
your program refers to hw
, in one or more of the object files it has already
added to the program, and that none of the object files it has already added
contains a definition for hw
.
If that is true, then the linker will extract a copy of my_lib.o
from the library and
add it to your program. Then, your program contains a definition for hw
, so
its references to hw
are resolved.
When you try to link the program like:
$ gcc -o eg1 -L. -lmy_lib eg1.o
the linker has not added eg1.o
to the program when it sees
-lmy_lib
. Because at that point, it has not seen eg1.o
.
Your program does not yet make any references to hw
: it
does not yet make any references at all, because all the references it makes
are in eg1.o
.
So the linker does not add my_lib.o
to the program and has no further
use for libmy_lib.a
.
Next, it finds eg1.o
, and adds it to be program. An object file in the
linkage sequence is always added to the program. Now, the program makes
a reference to hw
, and does not contain a definition of hw
; but
there is nothing left in the linkage sequence that could provide the missing
definition. The reference to hw
ends up unresolved, and the linkage fails.
Second, example 2, with shared library libz
A shared library isn’t an archive of object files or anything like it. It’s
much more like a program that doesn’t have a main
function and
instead exposes multiple other symbols that it defines, so that other
programs can use them at runtime.
Many Linux distros today configure their GCC toolchain so that its language drivers (gcc
,g++
,gfortran
etc)
instruct the system linker (ld
) to link shared libraries on an as-needed basis.
You have got one of those distros.
This means that when the linker finds -lz
in the linkage sequence, and figures out that this refers
to the shared library (say) /usr/lib/x86_64-linux-gnu/libz.so
, it wants to know whether any references that it has added to your program that aren’t yet defined have definitions that are exported by libz
If that is true, then the linker will not copy any chunks out of libz
and
add them to your program; instead, it will just doctor the code of your program
so that:-
-
At runtime, the system program loader will load a copy of
libz
into the
same process as your program whenever it loads a copy of your program, to run it. -
At runtime, whenever your program refers to something that is defined in
libz
, that reference uses the definition exported by the copy oflibz
in
the same process.
Your program wants to refer to just one thing that has a definition exported by libz
,
namely the function zlibVersion
, which is referred to just once, in eg2.c
.
If the linker adds that reference to your program, and then finds the definition
exported by libz
, the reference is resolved
But when you try to link the program like:
gcc -o eg2 -lz eg2.o
the order of events is wrong in just the same way as with example 1.
At the point when the linker finds -lz
, there are no references to anything
in the program: they are all in eg2.o
, which has not yet been seen. So the
linker decides it has no use for libz
. When it reaches eg2.o
, adds it to the program,
and then has undefined reference to zlibVersion
, the linkage sequence is finished;
that reference is unresolved, and the linkage fails.
Lastly, the pkg-config
variation of example 2 has a now obvious explanation.
After shell-expansion:
gcc -o eg2 $(pkg-config --libs zlib) eg2.o
becomes:
gcc -o eg2 -lz eg2.o
which is just example 2 again.
I can reproduce the problem in example 1, but not in example 2
The linkage:
gcc -o eg2 -lz eg2.o
works just fine for you!
(Or: That linkage worked fine for you on, say, Fedora 23, but fails on Ubuntu 16.04)
That’s because the distro on which the linkage works is one of the ones that
does not configure its GCC toolchain to link shared libraries as-needed.
Back in the day, it was normal for unix-like systems to link static and shared
libraries by different rules. Static libraries in a linkage sequence were linked
on the as-needed basis explained in example 1, but shared libraries were linked unconditionally.
This behaviour is economical at linktime because the linker doesn’t have to ponder
whether a shared library is needed by the program: if it’s a shared library,
link it. And most libraries in most linkages are shared libraries. But there are disadvantages too:-
-
It is uneconomical at runtime, because it can cause shared libraries to be
loaded along with a program even if doesn’t need them. -
The different linkage rules for static and shared libraries can be confusing
to inexpert programmers, who may not know whether-lfoo
in their linkage
is going to resolve to/some/where/libfoo.a
or to/some/where/libfoo.so
,
and might not understand the difference between shared and static libraries
anyway.
This trade-off has led to the schismatic situation today. Some distros have
changed their GCC linkage rules for shared libraries so that the as-needed
principle applies for all libraries. Some distros have stuck with the old
way.
Why do I still get this problem even if I compile-and-link at the same time?
If I just do:
$ gcc -o eg1 -I. -L. -lmy_lib eg1.c
surely gcc has to compile eg1.c
first, and then link the resulting
object file with libmy_lib.a
. So how can it not know that object file
is needed when it’s doing the linking?
Because compiling and linking with a single command does not change the
order of the linkage sequence.
When you run the command above, gcc
figures out that you want compilation +
linkage. So behind the scenes, it generates a compilation command, and runs
it, then generates a linkage command, and runs it, as if you had run the
two commands:
$ gcc -I. -c -o eg1.o eg1.c
$ gcc -o eg1 -L. -lmy_lib eg1.o
So the linkage fails just as it does if you do run those two commands. The
only difference you notice in the failure is that gcc has generated a
temporary object file in the compile + link case, because you’re not telling it
to use eg1.o
. We see:
/tmp/ccQk1tvs.o: In function `main'
instead of:
eg1.o: In function `main':
See also
The order in which interdependent linked libraries are specified is wrong
Putting interdependent libraries in the wrong order is just one way
in which you can get files that need definitions of things coming
later in the linkage than the files that provide the definitions. Putting libraries before the
object files that refer to them is another way of making the same mistake.
Автор | Тема: Если вылезает ошибка «undefined reference to vtable for …» [СОВЕТ] (Прочитано 57382 раз) |
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
Offline
Зарегистрирован: 01.11.2015
День добрый, помогите с ошибкой компиляции.
Проект в Atmel studio 7, среда ардуино 1.6.12.
Не пойму в чем проблема, при сборке проекта среда выдает следующие ошибки:
Severity Code Description Project File Line Error undefined reference to `IRrecv::decode(decode_results*)' project D:ardu_projectsLAMP_V3LAMP_V3projectSketch.cpp 36 Error ld returned 1 exit status project collect2.exe 0 Error recipe for target 'project.elf' failed project D:ardu_projectsLAMP_V3LAMP_V3projectDebugMakefile 130 Error undefined reference to `IRrecv::decode(decode_results*)' project D:ardu_projectsLAMP_V3LAMP_V3projectSketch.cpp 33 Error undefined reference to `IRrecv::enableIRIn()' project D:ardu_projectsLAMP_V3LAMP_V3projectSketch.cpp 26 Error undefined reference to `IRrecv::IRrecv(int)' project D:ardu_projectsLAMP_V3LAMP_V3projectSketch.cpp 16 Error undefined reference to `IRrecv::resume()' project D:ardu_projectsLAMP_V3LAMP_V3projectSketch.cpp 38
Проект прилагаю
Привествую.
Подозреваю что что то не до объявил.
Код:
C++ | ||
|
Выход после команды: gcc -o E:Dev-Cfile E:Dev-CFirst.cpp следующий:
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0xd):First.cpp: undefined re
ference to `std::string::size() const’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x60):First.cpp: undefined r
eference to `std::string::operator[](unsigned int) const’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x9f):First.cpp: undefined r
eference to `std::string::operator[](unsigned int) const’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0xce):First.cpp: undefined r
eference to `std::string::operator[](unsigned int) const’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x135):First.cpp: undefined
reference to `std::cout’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x13a):First.cpp: undefined
reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, c
har const*)’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x161):First.cpp: undefined
reference to `__gxx_personality_sj0′
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x195):First.cpp: undefined
reference to `std::cout’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x1a1):First.cpp: undefined
reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, c
har const*)’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x1ac):First.cpp: undefined
reference to `std::allocator<char>::allocator()’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x1cd):First.cpp: undefined
reference to `std::basic_string<char, std::char_traits<char>, std::allocator<cha
r> >::basic_string(char const*, std::allocator<char> const&)’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x1e0):First.cpp: undefined
reference to `std::allocator<char>::~allocator()’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x203):First.cpp: undefined
reference to `std::allocator<char>::~allocator()’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x215):First.cpp: undefined
reference to `std::string::c_str() const’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x22c):First.cpp: undefined
reference to `operator new[](unsigned int)’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x23a):First.cpp: undefined
reference to `std::string::c_str() const’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x26d):First.cpp: undefined
reference to `std::basic_string<char, std::char_traits<char>, std::allocator<cha
r> >::~basic_string()’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x2a8):First.cpp: undefined
reference to `std::basic_string<char, std::char_traits<char>, std::allocator<cha
r> >::~basic_string()’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x2fd):First.cpp: undefined
reference to `std::ios_base::Init::Init()’
D:Users18EE~1AppDataLocalTemp/ccQXcaaa.o(.text+0x318):First.cpp: undefined
reference to `std::ios_base::Init::~Init()’
collect2: ld returned 1 exit status