Undefined reference and bad reloc address when linking to libsndfile - c

In a project project I am working on, I need to be able to open and read content from audio files (at least WAV files). I installed libsndfile using the Win64 installer from mega-nerd.com, and created a simple C program that opens and closes an audio file to test out the library.
#include <stdio.h>
#include <sndfile.h>
int main()
{
SNDFILE *sndfPtr;
SF_INFO soundfileInfo;
char path[] = "C:\\Users\\jayb\\Documents\\MusicClips\\violin.wav";
printf( "Path: %s\n", path );
/* Open soundfile for reading */
soundfileInfo.format = 0; /* Must be set to zero before opening */
sndfPtr = sf_open( path, SFM_READ, &soundfileInfo );
if( sndfPtr == NULL )
{
fprintf( stderr, "Error: %s\n", sf_strerror(NULL) );
return -1;
}
/* Close soundfile and check for error */
if( sf_close( sndfPtr ) )
{
fprintf( stderr, "There was an error closing the soundfile\n" );
return -1;
}
return 0;
}
However, I keep getting undefined reference errors to the libsndfile functions, plus a bad reloc address error when I try compiling/linking:
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0xbb): undefined reference to `sf_open'
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0xd8): undefined reference to `sf_strerror'
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0x10a): undefined reference to `sf_close'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o: bad reloc address 0x20 in section `.eh_frame'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I'm compiling with this command:
gcc -Wall -o sndfile_test.exe sndfile_test.c -llibsndfile-1
The install of libsndfile comes with header files sndfile.h and sndfile.hh, and .lib, .def, and .dll files: libsndfile-1.lib libsndfile-1.def libsndfile-1.dll
The header and library directories are included in the compiler's search path, and it doesn't seem to be a problem of finding the library? I'm linking the .lib file with -llibsndfile-1 as per instructions on the minGW wiki
I also copied and renamed the .lib file with the .a extension and tried linking with -lsndfile-1 (this worked for someone else having a similar problem), but I get the exact same errors when I do so.
Any help would be appreciated! If I cannot link successfully to libsndfile, are there are any other simple libraries out there I could use for reading from audio files?
Edit: Of course I spend two days trying to find the solution, finally post to stackoverflow, and then solve the problem two hours later. I will post my solution as an answer to the question.

Following the information on this page of the MinGW wiki, use MinGW's dlltool with the libsndfile-1.def file to re-create the the dll's import library.
Use this command to do so:
dlltool -d libsndfile-1.def -l libsndfile-1.dll.a
This will create the .dll.a file that you can use instead of the .lib file. Note that when I did this, the .dll.a file did not appear in the directory I was in when I executed the above command. It ended up hidden in my \AppData directory, so you might have to search your OS for it.
Replace the libsndfile-1.lib in your lib directory with libsndfile-1.dll.a and then compile using:
gcc -Wall -o sndfile_test.exe sndfile_test.c -lsndfile-1

Related

Undefined reference to (Quickmail)

I am looking for how to install quickmail.
I put quickmail.h here: C:\Program Files\CodeBlocks\MinGW\include, the .a and .la here: C:\Program Files\CodeBlocks\MinGW\lib.
I linked these .a files by adding them in the linker settings. I also did include the library like this: #include <quickmail.h>, but the functions are not recognized.
What should I do ?
The 4 files in the bin folder are in the project folder and I downloaded files from here : quickmail - Sourceforge.
EDIT : I get \main.c|9|undefined reference to '__imp_quickmail_initialize'| \main.c|10|undefined reference to '__imp_quickmail_create'| \main.c|11|undefined reference to '__imp_quickmail_set_body' and I put C:\Program Files\CodeBlocks\MinGW\include in search directories.
This is the code :
#include <stdio.h>
#include <stdlib.h>
#include <quickmail.h>
int main()
{
const char* error;
quickmail_initialize();
quickmail mailobj = quickmail_create("aaa#gmail.com", "libquickmail test e-mail");
quickmail_set_body(mailobj, "This is a test e-mail.\nThis mail was sent using libquickmail.");
quickmail_add_attachment_file(mailobj, "words.txt", NULL);
if ((error = quickmail_send(mailobj, "smtp.gmail.com", 587, "aaa#gmail.com", "MAGA2020")) != NULL)
fprintf(stderr, "Error sending e-mail: %s\n", error);
quickmail_destroy(mailobj);
return 0;
}
Sorry, the site gave me the wrong version.
To use a library you need to include the header in the code (in this case #include <quickmail.h>) and if needed tell the compiler where to find this file (the full path to the lib folder) with the -I compiler flag.
Next you need to tell the linker to link with the library (in this case -lquickmail or -lquickmaillight) and if needed where to find this file (the full path to the lib folder) with the -L linker flag.
Your errors are linker errors, so it seems the second step wasn't properly done.
In Code::Blocks it looks like this (though unlike the screenshots you should set it at the top-level instead of just for Debug builds):

Connect Postgresql in C

I'm trying to connect a C script running on Windows to my Postgresql database.
For the moment, I got this script on a website :
#include <stdio.h>
#include "libpq-fe.h"
#include <string>
#include <stdlib.h>
int main() {
PGconn *conn;
PGresult *res;
int rec_count;
int row;
int col;
conn = PQconnectdb("dbname=ljdata host=localhost user=dataman password=supersecret");
if (PQstatus(conn) == CONNECTION_BAD) {
puts("We were unable to connect to the database");
exit(0);
}
res = PQexec(conn,
"update people set phonenumber=\'5055559999\' where id=3");
res = PQexec(conn,
"select lastname,firstname,phonenumber from people order by id");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
puts("We did not get any data!");
exit(0);
}
rec_count = PQntuples(res);
printf("We received %d records.\n", rec_count);
puts("==========================");
for (row=0; row<rec_count; row++) {
for (col=0; col<3; col++) {
printf("%s\t", PQgetvalue(res, row, col));
}
puts("");
}
puts("==========================");
PQclear(res);
PQfinish(conn);
return 0;
}
I copied the libpq-fe.h, the postgres_ext.c and the pg_config_ext.c to avoid the errors.
and now I have all this errors :
undefined reference to 'PQconnectdb'
undefined reference to 'PQresultStatus'
...
So obviously I don't have the file.c which contains all the functions I need but I can't find it.
I saw on another forum I need to create a makefile to tell the compiler to use the libpq.dll (I have this file) but I haven't the knowledge to do that.
How can I make this working ?
EDIT
So now when I try to compile it like that :
gcc -I "C:\Program Files\PostgreSQL\9.6\include" -L "C:\Program Files\PostgreSQL\9.6\lib" test.c -lpq
And I get the error :
C:\Program Files\PostgreSQL\9.6\lib/libpq.dll: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
I think it's near to the final solution.
From the research I made, I found that libpq.dll is 32bit, but my environnement is 64bit. do this change anything ?
EDIT 2
The compilation now works correctly with this line :
gcc -m64 -I "C:\Program Files\PostgreSQL\9.6\include" -L "C:\Program Files\PostgreSQL\9.6\lib" test.c -lpq -o test.exe
But when I double-click on the .exe I have the following error :
"Unable to start the program because LIBPQ.dll is missing"
So it clearly means that I have to link the libpq.dll with probably a link to Program Files/PG/9.6/lib.
The problem here is that I want to build a standalone .exe which probably embed the Postgresql lib to works correctly even if the computer target haven't Postgresql installed on it
(This is possible, for example in Java when we build a Jar with all the external lib copied in)
Is it possible in C ? I think I need to adapt my compilation line but I don't found which parameter I can add to import all the needed lib in the .exe
From your edits I see that you have figured out how to use the -I and -L options of gcc by now. Good.
I guess your relaining problem is that you are trying to link with a 64-bit libpq.dll in 32-bit mode or vice versa.
You can set the mode with the gcc options -m32 and -m64.
You can examine the shared library with file libpq.dll, that should tell you if it is a 32-bit or a 64-bit library.
If gcc tells you something like: 64-bit mode not compiled in, you need to install an appropriate version of gcc.
To solve the problem that libpq.dll is not found at run time, either put the directory where it resides into the PATH environment variable, or use the option -Wl,-rpath,<directory with libpq.dll>.

undefined symbol: _open_osfhandle, handle to file descriptor, linking error

In a shared library I'm trying to convert a self created handle to a file descriptor so that I can run fsync on that file descriptor. I really have two questions, the first is bellow and the second is if there is some other way to get a file descriptor from a handle.
I include "#include " to my code and then call the code bellow:
int _open_osfhandle(intptr_t oshandle, int flags);
int fd = _open_osfhandle((intptr_t)(handle), 0);
fsync(fd);
This compiles correctly but it does not work when I execute the code I get the following in the logs:
undefined symbol: _open_osfhandle
This usually means there is a linking error when creating the shared library but the correct libraries are linked while compiling the code. io.h is a part of:
rpm -qf /usr/include/sys/io.h
glibc-headers-2.17-105.el7.x86_64
Which should be the standard C library for redhat, which I Included in my ccmake build file:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -pthread")
But I still get the error that the symbol is undefined.
I've tried to work around this by attempting to create my FD with the bellow command but I believe it did not work.
int fd = (uintptr_t)(handle);
Any ideas as to why this issue is coming up.
Also is there some other way for me to get a file descriptor from my created handle?

Tcl interpreter undefined reference error while compiling with gcc

I am new to Tcl scripting and would like to use C to embed Tcl codes.
This is the code that I have copied from a website to test the Tcl-C working.
test.c
#include <stdio.h>
#include <tcl.h>
void main ()
{
Tcl_Interp *myinterp;
char *action = "set a [expr 5 * 8]; puts $a";
int status;
printf ("Your Program will run ... \n");
myinterp = Tcl_CreateInterp();
status = Tcl_Eval(myinterp,action);
printf ("Your Program has completed\n");
getch();
}
I am using MinGW to compile this file.
I have copied the contents of the C:\Tcl\include folder into the C:\MinGW\include folder as well.
My gcc command for compiling :
gcc -o test.exe test.c
The error message shown :
C:\Users\user\AppData\Local\Temp\ccEHJKCb.o:tcl_connection_test.c:(.text+0x23): undefined reference to `_imp__Tcl_CreateInterp'
C:\Users\user\AppData\Local\Temp\ccEHJKCb.o:tcl_connection_test.c:(.text+0x3d): undefined reference to `_imp__Tcl_Eval'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\ccEHJKCb.o: bad reloc address 0x20 in section `.eh_frame'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I don't seem to have any libtcl file in the Tcl folder.
The Tcl version is ActiveTcl 8.5.15.0.297577.
Any help would be really appreciated.
Your example how to embed Tcl is outdated, and you are missing certain things in your link line (-ltcl85 for example). If you simply add -ltcl85 to your link line it should start to work.
It does not work in your case, because you installed the x64 (64-Bit version) of ActiveTcl, which provides x64 dlls, not 32-Bit ones. But the standard mingw gcc only works with 32-Bit libraries.
So to get this to work:
Download the 32-Bit ActiveTcl distribution
Compile your code with gcc -o test.exe test.c -Lc:/tcl/lib -Ic:/tcl/include -ltcl86
Adjust your path so the c:\tcl\bin\tcl86.dll is found in PATH, make also sure Tcl finds its libdir (set TCL_LIBRARY=c:\tcl\lib\tcl8.6)
run your program
But for more complex examples, you still need to initialise the library and a do some boilerplate code, so please call Tcl_FindExecutable(argv[0]); before the call to Tcl_CreateInterp() otherwise a few commands (e.g. clock might just not work as expected).
Have a look at http://www.tcl.tk/cgi-bin/tct/tip/66.html for some more details. Also have a look at the Tcl source distribution and the source for the tclsh shell.
You're very close to getting it right.
The Tcler's Wiki has a few examples, some of which are very confusing to be frank, but this one from this page is the best I've spotted recently. (The comments are mine.)
#include <stdlib.h>
#include <tcl.h>
int main (int argc, char *argv[]) {
Tcl_Interp *interp;
const char *script = "proc p1 a { puts $a }";
// Initialize the Tcl library; ***STRONGLY RECOMMENDED***
Tcl_FindExecutable(argv[0]);
// Create the interpreter, the execution context
interp = Tcl_CreateInterp();
// Initialise the interpreter
if (TCL_OK != Tcl_Init(interp)) {
fprintf(stderr, "Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
exit(EXIT_FAILURE);
}
// Define a procedure
Tcl_Eval(interp, script);
fprintf(stderr, "res 1: %s\n", Tcl_GetStringResult(interp));
// Check if the procedure exists
Tcl_Eval(interp, "puts [info commands p*]");
fprintf(stderr, "res 2: %s\n", Tcl_GetStringResult(interp));
// Call the procedure
Tcl_Eval(interp, "p1 abc");
fprintf(stderr, "res 3: %s\n", Tcl_GetStringResult(interp));
// We could use Tcl_DeleteInterpreter to clean up here, but why bother?
return EXIT_SUCCESS;
}
What else were you missing? Simple. You forgot to tell the C compiler to use the Tcl library when building the executable; the compiler (or, more strictly, the linker) is in places a stupid piece of code. The exact option to use to get the linker to add the library in will depend on your system configuration, but is probably going to be -ltcl, -ltcl8.5 or -ltcl8.6; which it is depends on the filename and all sorts of things that we can't check exactly without being on your system. The names do fit a simple pattern though.
It's also possible that you might need to pass the -L option in to tell the linker about additional library locations. (There's an equivalent -I for telling the compiler where to find include files, so you don't have to copy everything into one gigantic unmanageable directory.)
The order of arguments can matter. Libraries should be listed after the source file:
gcc -o test.exe test.c -L/mingw/path/to/library/directory -ltcl86
(If you're using old, unsupported versions of Tcl — why would you do that?! — then the code above won't work because Tcl_Eval then took a writable string. But that was fixed many years ago and upgrading to a current version is the fix.)

Build Error with CalcOpticalFlowFarneback Function -> OpenCV -> C Language - Eclipse -> MacOSX

i have to do a program using C Language and OpenCV Libreries for a project,
I followed the guide for the installation for MACOSX on this site:
OpenCV Installation
I used Mac Port for the Istallation.
I use Eclipse to program,
Now when i try to compile this program, i get a Build Error and i think that it depends to CalcOpticalFlowFarneback() Function.
This is the code:
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>
#include <time.h>
int main(){
CvCapture* webcam = cvCreateCameraCapture(0);
IplImage*prev=NULL;
IplImage*next=NULL;
char scelta;
/*INIZIALIZZAZIONE FUNZIONE RAND*/
srand(time(NULL));
double pyr_scale=0.5;
int levels=1;
int winsize=3;
int iterations=10;
int poly_n=5;
double poly_sigma=1.1;
int flags=0;
sleep(2);
if (!webcam){
/* Exit with an error */
puts("Attenzione! si è verificato un Errore in Fase di Attivazione della WebCam. Preghiamo di Riprovare!");
return -1;
}
while (1) {
prev = cvQueryFrame(webcam);//primi 8-bit single-channel immagine in ingresso
next = cvQueryFrame(webcam);// immagine secondo ingresso della stessa dimensione e lo stesso tipo prev.
CvSize isize = cvSize(80,80);
IplImage *flow = cvCreateImage(isize, IPL_DEPTH_32F, 1); //immagine computerizzata che ha le stesse dimensioni e tipo CV_32FC2 prev
if ((prev) && (next)) {
cvCalcOpticalFlowFarneback(prev,next,flow,pyr_scale,levels,winsize,iterations,poly_n,poly_sigma,flags);
scelta=cvWaitKey(20);
if((char)scelta == 27){
break;
}
}
}
cvDestroyWindow("VIDEO SORVEGLIANZA");
cvReleaseCapture(&webcam);
return 0;
}
and this is the error Log:
Undefined symbols for architecture x86_64: "_cvCalcOpticalFlowFarneback", referenced from:_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [cattura_foto] Error 1
And I want to specify that if i remove the cvCalcOpticalFlowFarneback Function i do not have any problems.
Thank you,
manu.web
"undefined symbol" means that you have not linked against the proper library, or you have, but the library is for the wrong architecture (e.g. a 32-bit library while your machine is 64-bit).
You need to check the linking flags and paths, and the library installation path.
If you can get the linker log in Eclipse, and/or the command line that got passed to the linker, you can repeat the linking command from a terminal and see if you get a more helpful message (such as "library not found"). Or you can try running the make command from the terminal and do the same.
Editing the Makefile, you might find that some commands are prepended with the "#" symbol, which prevents them from being output (their output is visible, the command itself is not). You can usually safely remove the #'s and get a more verbose output.
Another possibility is that there is a name mangling error, and the "_" prefix to the function should not be there. I am not too familiar with Eclipse though, so I can't follow you there. But see e.g. http://www.eclipse.org/forums/index.php/m/783606/ ; you might have built OpenCV with the wrong options, so that now it is not compatible with your code. Which is strange, seeing as how you call other OpenCV functions without problems; but maybe you built OpenCV in two steps?
In general (this is not limited to OpenCV!) you will have a build command such as
gcc -I/usr/local/include/opencv -L/usr/local/lib main.c -o Cattura_foto2 \
-lopencv_core.2.4.3 \
-lopencv_imgproc.2.4.3 \
-lopencv_highgui.2.4.3 \
-lopencv_gpu.2.4.3
and an error complaining of an undefined symbol:
Undefined symbols for architecture x86_64: "_cvCalcOpticalFlowFarneback"
This means that you are linking with the libraries openvc_core.2.4.3 etc. and the linker cannot find the symbol "_cvCalcOpticalFlowFarneback".
Locate those libraries on your computer, and run (from Terminal) the following command against all the libraries you found. Note: your path will probably be different. I have /usr/lib64.
for lib in /usr/lib64/libopencv_*; do
echo "Examining $lib..."
strings $lib | grep -i cvCalcOpticalFlowFarneback
done
You ought to see something like:
Examining /usr/lib/libopencv_pippo_pluto...
Examining /usr/lib/libopencv_blah_blah...
...
Examining /usr/lib64/libopencv_video.so...
cvCalcOpticalFlowFarneback
cvCalcOpticalFlowFarneback
Examining /usr/lib64/libopencv_video.so.2.4...
cvCalcOpticalFlowFarneback
cvCalcOpticalFlowFarneback
Examining /usr/lib64/libopencv_video.so.2.4.3...
cvCalcOpticalFlowFarneback
cvCalcOpticalFlowFarneback
The reason for the multiple matches is that libraries exist in multiple symbolic copies.
To be sure, let's inspect the library:
nm -D /usr/lib64/libopencv_video.so.2.4 | grep Farneback
0000000000027e50 T cvCalcOpticalFlowFarneback
Now we know two important things:
The symbol is really called cvCalcOpticalFlowFarneback. Your GCC is complaining it doesn't find the symbol _cvCalcOpticalFlowFarneback, with an underscore. You either built the library incorrectly or you are missing a -fno-leading-underscore option to GCC.
But if that were the case, no OpenCV2 symbols at all would be recognized. So, I'm betting on #2:
The symbol is in libopencv_video.so.2.4.3, and there is no reference to that library in your build command! You ought to have -lopencv_video.2.4.3 or something like that. Verify your makefile and options.
Let me know how it goes - and in bocca al lupo.

Resources