开发者

Error when linking CGI (C programming ) with Mysql

Hi I'm using CGI which is written with C and MySql.

Here is my sample page.

 // save user 
void saveUser(char *name, char *pwd,char *role)
{

    char  query[500];
    memset(query,0,500);
    conn = mysql_init(NULL);

    /* Connect to database */
    if (!mysql_real_connect(conn, server,
    user, password, database, 0, NULL, 0)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
   }

    /* send SQL query */
    sprintf(query,"insert into userTbl(name,password,role) values (\'%s\',\'%s\',\'%s\'); ",name,pwd,role);
    if (mysql_query(conn, query)) 
    {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(2);
   }

    /* close connection */
    mysql_close(conn);
}

I got this error whenever I put the page in my CGI folder.

undefined reference to `mysql_init'

undefined reference to `mysql_connect'

undefined reference to `mysql_select_db' and other mysql related errors. When I search the solution on the web It says that I've to link my page with mysql client library like that

gcc -o a $(mysql_config --cflags) saveUser.c $(mysql_config --libs)

First Question Does it mean I can't use saveUser.c in my CGI directly?

It shows the same error whenever I put saveuser.c in the CGI folder. I can only put the a script I created. So I decide to call the a script from the CGI by using system("a %s %s %s",arg[0],arg[1],arg[2]) Then I can save the user . Everything is ok.

But I got another problem when I try to retrieve the data from the database. I don't know how to get the data from the database using a generated script. I've to show the lists of users on my web site. Here is my code for retrieval.

// get users
void getAll()
{

    char  query[500];
    char result[1024];
    memset(result,0,1024);
    memset(query,0,500);
    conn = mysql_init(NULL);

    /* Connect to database */
    if (!mysql_real_connect(conn, server,
    user, password, database, 0, NULL, 0)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
   }

    /* send SQL query */
    sprintf(query,"select * from userTbl");
    if (mysql_query(conn, query)) 
    {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(2);
   }
    res = mysql_use_result(conn);

    /* output table name */
    system("clear");
    sprintf(result,"ID\t Name\t Password\t Role\n");
        while ((row = mysql_fetch_row(res)) != NULL)
    {
         //printf("%s \n", row[0]);
        //strcpy(id,row[0]);
        sprintf(query,"%s\t %s\t %s\t\t %s\n",row[0], row[1], row[2], row[3]);
        strcat(result,query);
    }
    /* close connection */
    mysql_free_result(res);
    mysql_close(conn);
    printf(result); 
}

Second Question What's the best way to overcome this problem. Can I use the script like a in my CGI or How can I use getAll.c in my CGI directly.

Can anybody help me with my problem? I just learn CGI 1.5 months ago and C just 2.5 months ago. Sorry about my ignorance.

Thanks in advance.

Update :

here is my top level Makefile

    ROOT=.
     CURDIR=$开发者_运维技巧(shell /bin/pwd)
     JITCOMM_INSTALL=$(ROOT)/install

     include $(ROOT)/Makefile.basic

     #set root directory
     SUB_DIRS = cgi_src
     SUB_DIRS += check_update
     SUB_DIRS += loadconfig
SUB_DIRS += keepalive
SUB_DIRS += script
SUB_DIRS += server
SUB_DIRS += startproxy
SUB_DIRS += net_stats
#SUB_DIRS += ../sniffer_gui
#SUB_DIRS += java 

all:
ifneq ($(SUB_DIRS), )
        @for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
        cd $(CURDIR)/$${i}; make || exit; cd $(CURDIR); done
endif

clean:
        @rm -f $(ROOT)/lib/*
        @rm -rf $(JITCOMM_INSTALL)
ifneq ($(SUB_DIRS), )
        @for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
        cd $(CURDIR)/$${i}; make clean || exit; cd $(CURDIR); done
endif


install: all
        @rm -rf $(JITCOMM_INSTALL)
        @mkdir $(JITCOMM_INSTALL)
        @mkdir $(JITCOMM_INSTALL)/etc
        @mkdir $(JITCOMM_INSTALL)/etc/acpro
        @mkdir $(JITCOMM_INSTALL)/etc/syslog-ng
        @mkdir $(JITCOMM_INSTALL)/etc/apache2
        @mkdir $(JITCOMM_INSTALL)/etc/apache2/sites-available
        @mkdir $(JITCOMM_INSTALL)/var
        @mkdir $(JITCOMM_INSTALL)/var/www
        @mkdir $(JITCOMM_INSTALL)/var/www/cgi-bin

Here is my Makefile in cgi-src folder

ROOT=../
CURDIR=$(shell /bin/pwd)

include $(ROOT)/Makefile.basic

#set root directory
SUB_DIRS = util
SUB_DIRS += cgi_util
SUB_DIRS += cgi_module

#Must be last
SUB_DIRS += cgi_main

all:
ifneq ($(SUB_DIRS), )
        @for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
        cd $(CURDIR)/$${i}; make || exit; cd $(CURDIR); done
endif

clean:
ifneq ($(SUB_DIRS), )
        @for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
        cd $(CURDIR)/$${i}; make clean || exit; cd $(CURDIR); done
endif


install:

ifneq ($(SUB_DIRS), )
        @for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
        cd $(CURDIR)/$${i}; make install || exit; cd $(CURDIR); done
endif

Here is my Makefile.basic

CC=/usr/bin/gcc
#CC=powerpc-linux-gcc
CP=/usr/bin/cp
CFLAGS=-g -Wall $(shell mysql_config --cflags) $(shell mysql_config --libs)

www=/var/www
htdocs=/htdocs
cgi_bin=/cgi-bin
config=/etc/apache2/sites-available/default


INSTALL_DIR=$(pwd)/.install

Here is part of my error

 /usr/bin/gcc -c -g -Wall -I/usr/include/mysql  -DBIG_JOINS=1 -fPIC fno-strict- aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -I../include -o cgi_func.o cgi_func.c
 /usr/bin/gcc -c -g -Wall -I/usr/include/mysql  -DBIG_JOINS=1 -fPIC -fno-strict-aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -I../include -o cgic.o cgic.c
 /usr/bin/gcc -g -Wall -I/usr/include/mysql  -DBIG_JOINS=1 -fPIC -fno-strict-aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -static -o cgi_main  cgi_func.o  cgic.o -lcgi_util -lcgi_module -lutil -L../../lib -lm
 ../../lib/libcgi_module.a(users.o):(.data.rel.local+0x8): multiple definition of `password'
 ../../lib/libcgi_module.a(password.o):/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/password.c:292: first defined here
 /usr/bin/ld: Warning: size of symbol `password' changed from 193 in ../../lib     /libcgi_module.a(password.o) to 4 in ../../lib/libcgi_module.a(users.o)
 /usr/bin/ld: Warning: type of symbol `password' changed from 2 to 1 in ../../lib/libcgi_module.a(users.o)
 ../../lib/libcgi_module.a(users.o): In function `save':
 /home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/users.c:17: multiple definition of `save'
 ../../lib/libcgi_module.a(mode.o):/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/mode.c:56: first defined here
 ../../lib/libcgi_module.a(users.o): In function `saveUser':
 users.c:(.text+0x1cb): undefined reference to `mysql_init'
 users.c:(.text+0x22d): undefined reference to `mysql_real_connect'
 users.c:(.text+0x241): undefined reference to `mysql_error'
 users.c:(.text+0x2bd): undefined reference to `mysql_query'
 users.c:(.text+0x2d1): undefined reference to `mysql_error'
 users.c:(.text+0x30d): undefined reference to `mysql_close'


You have answered your own question, if you get undefined references to MySQL, you are not linking it correctly. You need to compile with:

gcc -o a $(mysql_config --cflags) saveUser.c $(mysql_config --libs)

This has nothing to do with how your code looks/works, only how the compiler/linker combines the source files into an executable. If you post a part of your Makefile instead of your code maybe you could get more pointers on the issue.

EDIT: Ok, can you add $(mysql_config --cflags) $(mysql_config --libs) to your CFLAGS declaration in Makefile.basic and see what happens?

EDIT2: The line causing the error seems to be:

 /usr/bin/gcc -g -Wall -I/usr/include/mysql  -DBIG_JOINS=1 -fPIC -fno-strict-aliasing -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -static -o cgi_main  cgi_func.o  cgic.o -lcgi_util -lcgi_module -lutil -L../../lib -lm

A bit odd, since (I assume) the correct libraries are linked (-lmysqlclient)... double check that you don't have multiple versions of the mysql library installed, or that these functions are defined in a different library. The easiest way to go about it would be to create a minimal project with just these mysql-functions and try to link it. If that doesn't work there is your problem. If it does work I'm not sure where to go next.

You should look into these multiple definitions warnings by the way, looks nasty... check if you have global variables defined in a header file somewhere. The project you are working on seems to partition all it's code in different libraries and link these at the end, maybe you need to clean all of it (remove .o and .a files) and run make again?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜