I used search.h for my c program, where I need to put #define _GNU_SOURCE to the first line in order to introduce multiple hash tables. But after that, errors like undefined reference to 'log10' and undefined reference to 'PQntuples' popped up. I certainly need all the packages there, how should I now compile the program? Any help would be deeply appreciated! Thanks.
The headers:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string.h>
// library for psql
#include <libpq-fe.h>
#include <unistd.h>
#include <time.h>
#include <search.h>
int main(void){
char host[] = "localhost";
char port[] = "5432";
char db_name[] = "db_name";
char user[] = "test_usr";
char password[] = "123456";
sprintf(db_str, "host=%s port=%s dbname=%s user=%s password=%s",
host, port, db_name, user, password);
PGconn *db_connection = DBConnect(db_str);
struct hsearch_data htab;
hcreate_r(10, &htb);
ENTRY e, *ep;
e.key = "test";
e.data = (void *) 1;
hsearch_r(e, ENTER, &ep, &htab);
}
And this was how I compile the file:
gcc -Wall -Wextra -I/home/userX/postgresql/include -L/home/userX/postgresql/lib -lm -lpq -g my_program.c
Specifiy the libraries at the end of the command line
gcc -Wall -Wextra -I/home/userX/postgresql/include \
-L/home/userX/postgresql/lib -g my_program.c -lpq -lm
// ^^^^^^^^
gcc looks at required symbols left to right on the command line.
With the libraries before the source files, when gcc processes the -llib argument it does not have any requirements and therefore does not "extract" any function from the library.
Related
I want to to run a simple program, using vs code, which includes three files: main.c item.c item.h.
I understand that I there is a way to link things together, but I don't know how. Can you explain me how to do it?
I've tried also to add the extension to make a project, but I didn't understand how to.
Here's the code:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "item.h"
int main () {
int a = 2;
int b = 3;
int res;
res = prod(a,b);
printf("%d ", res);
return 0;
}
item.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "item.h"
int prod(int a, int b) {
return a*b;
}
item .h
#ifndef ITEM_H
#define ITEM_H
int prod(int a, int b);
#endif
I don't know if you are using Windows or Linux or Mac, I'm going to explain it for Linux but the method is similar for the others.
First of you go on VS Code, then you click on new file and rename it "makefile", then you write this:
link: item.o main.o
gcc item.o main.o -o programName
main.o:
gcc -c main.c
item.o:
gcc -c item.c
clear:
rm -f item.o main.o programName //this one is to delete files faster
Once you wrote the makefile you write in the terminal the command make and you get the executable file for your program.
However in item.c you aren't using any of the library you included, you only need to include item.h; last thing, I don't know why you are doing the #ifndef thing but it seems a waste.
i kept the essential.
caller.exe loads the dll, then calls the function dll_init declared inside the dll.
this last function calls the function "get_ptr" declared in the common library which should return a pointer to the global variable.
the issue is:
whenever caller.exe calls "get_ptr" it returns a valid pointer same as the one which was previously allocated on caller.exe start fine.
whenever the dll thru it function "dll_init" (after bein called by
caller.exe) calls "get_ptr" (knowing that the dll is linked to the
static lib) it return NULL pointer.
what i am missing ?
libcommon.c
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/***************header****************/
int *get_ptr(void);
int set_ptr(void);
/**********************************/
int *global=NULL;
//extern __declspec(dllimport) int *global; doesnt work
int set_ptr() {
global = (int *) malloc(sizeof(int));
printf("global allocated to %p\n",global);
*global=485; //random value
return 0;
}
int *get_ptr() {
return global;
}
here is compiling commands (makefile simplified):
gcc.exe -c libcommon.c -o libcommon.o -m32
ar r libcommon.a libcommon.o
ranlib libcommon.a
module.c
#include <windows.h>
#include <stdio.h>
#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif
DLLIMPORT int dll_init(void) {
int *ptr=(int *) get_ptr();
puts("dll run");
printf("from dll global: %p\n",ptr);
puts("dll end");
return 0;
}
compiling:
gcc.exe -c module.c -o module.o -m32 -DBUILDING_DLL=1
gcc.exe -shared module.o -o module.dll -static-libgcc -lws2_32 -m32 -s -L"." -lcommon -Wl,--output-def,libmodule.def,--out-implib,libmodule.a,--add-stdcall-alias
caller.c
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef void(voidfunc)(void);
voidfunc *fct_ptr;
int test(int a) {
printf("%d",a++);
}
int main() {
set_ptr();
printf("::%p\n",get_ptr());
/* Load the dll then call dll_init */
HMODULE dllptr = LoadLibrary("module.dll");
if (dllptr != NULL) {
fct_ptr = (voidfunc *) GetProcAddress(dllptr, "dll_init");
puts("loaded");
if (fct_ptr != NULL)
fct_ptr();
FreeLibrary(dllptr);
}
}
compiling:
gcc.exe caller.c -o caller.exe -m32 -static-libgcc -lws2_32 -L. -lcommon -m32
I believe you have 2 different places in memory named global. One is
in caller since you compiled it statically with lcommon. Data is set
there via set_ptr. Second is in module space (for the same reasons),
but you never called set_ptr() there. Check memory address of global
inside dll_init and in main. If they are not the same, you then need
to call set_ptr in your `dll_init``
he's right, i think the common static library linked with both exe and dll was a wrong idea.
the solution is here: .dll Plugin that uses functions defined in the main executable
Any other suggestions are welcome
I have my main C file:
#if defined(WIN32)
#include <windows.h>
#include <stddef.h>
#endif
#if defined(LINUX)
#include <curses.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(WIN32)
#include <conio.h>
#endif
#include <ctype.h>
#include <a429usbnt.h>
#if defined(WIN32)
#include "genlib.h"
#endif
void main()
{
_open_xpc(1);
}
When I try to compile using this command
gcc -I. -L. test.c -o test
I get the following error: undefined reference to '_open_xpc'.
However if I change the call to the _open_xpc function and instead just
printf("%d", XPC_ERROR_ACTIONCODE);
the program compiles fine and the correct value assigned to the definition of XPC_ERROR_ACTIONCODE is printed out, so the compiler is linking a429usbnt.h but will only recognize defined variables and not the functions.
If you are trying to link against a .lib file with gcc, it seems you need to define a directory with -L and an actual file with -l
display.h
#ifndef PRO_DISPLAY_H
#define PRO_DISPLAY_H
/** Initializes the display **/
int pro_display_init(void);
#endif /* PRO_DISPLAY_H */
display.c
#include "main.h"
static int height_ = 300;
static int width_ = 300;
static int bpp_ = 16;
static SDL_Surface* screen_ = NULL;
int pro_display_init(void)
{
screen_ = SDL_SetVideoMode(width_, height_, bpp_, SDL_HWSURFACE|SDL_DOUBLEBUF);
if (!screen_)
{
pro_sdl_error("Video initialization failed.");
return 0;
}
return 1;
}
main.h
#ifndef PRO_MAIN_H
#define PRO_MAIN_H
// standard headers
#include <stdlib.h>
#include <stdlib.h>
// conditional headers
#if defined(WIN32) || defined(_WIN32)
#include <windows.h>
#endif
// our own headers
#include "scripter.h"
#include "ttf_util.h"
#include "events.h"
#include "display.h"
// some macros
#define pro_error(...) fprintf(stderr, __VA_ARGS__)
#define pro_sdl_error(x) fprintf(stderr, "%s. \n=> %s\n", x, SDL_GetError())
#define pro_ttf_error(x) fprintf(stderr, "%s. \n=> %s\n", x, TTF_GetError())
#endif /* PRO_MAIN_H */
** main.c**
#include "main.h"
int main(int argc, char* argv[])
{
pro_display_init();
return 0;
}
The Error:
main.c|5|undefined reference to `pro_display_init()'|
Checked the build process. Made sure I was adding "display.c" to gcc's input files. I'm at my wit's end. Why the error?
display.c and main.c are compiled into their own "translation unit". What happens is that when trying to resolve symbols name (i.e. looking for pro_display_init), the C compiler thinks it's compiling a standalone .c unit. The proper way to go is to compile them separately and then link them, e.g.
gcc -c display.c # creates display.o
gcc main.c display.o # compiles main.o and then link with display.o
Of course, you'll be creating/reusing a Makefile soon that lets you define rules for all this.
I think, #include "main.h" or #include "display.h" (in main.h) "finds" the wrong include file. Check you include_path variable.
Given this code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <pthread.h>
#define BUF_SIZE 256
int main()
{
key_t key;
char *virtualaddr;
sem_t *get, *put;
int shmid;
const char* messageOne = "Hello world , I'm child number 1\n";
const char* messageTwo = "Hello world , I'm child number 2\n";
char buf[BUF_SIZE];
key = ftok("anyfile",'R');
shmid = shmget(key,1024,0644|IPC_CREAT);
...
...
shmctl (shmid, IPC_RMID, NULL);
exit(EXIT_SUCCESS);
}
I get from eclipse undefined reference to sem_open .
I've check with this post since this question is very similar to mine , but didn't understand exactly where is my mistake ,
Can you please explain where do I need to fix it / add another compilation command (if this is indeed the case) ?
Much appreciated
You need to include -lpthread when compiling. This is used by the linker, to link your binary against the library.
The other answers already cover how to do this on the command line.
To do this in Eclipse, you need to follow the directions here:
In the project properties, go to : C/C++ Build --> Settings. Then
"Tool Settings", select "Libraries" under "Linker". You can add all
your project libraries there (without the "-l"). Also in the lower
part, you can add custom path to search libraries
When linking, you have to add the flag -pthread or -lrt to the command line. It's right there in the manual page.
As it is written in the first answer in the question you linked, you nedd to compile it in this way:
gcc source.c -lpthread
-lrt or -pthread will do the same.