Вроде нарыл что да как, но проблема, всё равно не получается, может гуру си пояснят, что да как. Я относительно не давно начал программить на си.
Вот программа:
#include <mysql/mysql.h>
#include <stdio.h>
void main(void)
{
MYSQL *mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char *query;
int t,r;
mysql_init(mysql);
if (!mysql_real_connect(mysql,"localhost","root",
"","cybeast",0,NULL,0))
{
printf( "Error connecting to database: %s\n",mysql_error(mysql));
}
else printf("Connected...\n");
query="select * from test";
t=mysql_real_query(mysql,query,(unsigned int) strlen(query));
if (t)
{
printf("Error making query: %s\n",
mysql_error(mysql));
}
else printf("Query made...\n");
res=mysql_use_result(mysql);
for(r=0;r<=mysql_field_count(mysql);r++){
row=mysql_fetch_row(res);
if(row<0) break;
for(t=0;t<mysql_num_fields(res);t++){
printf("%s ",row[t]);
}
printf("\n");
}
mysql_close(mysql);
}
---
Всё как в мануалах...
А вот что выдаётся при "компилинге":
root@ch00r:~/mysql# gcc mysql2.c -o mysql
mysql2.c: In function `main':
mysql2.c:5: warning: return type of `main' is not `int'
/tmp/ccoxWTgs.o(.text+0x17): In function `main':
: undefined reference to `mysql_init'
/tmp/ccoxWTgs.o(.text+0x3c): In function `main':
: undefined reference to `mysql_real_connect'
/tmp/ccoxWTgs.o(.text+0x51): In function `main':
: undefined reference to `mysql_error'
/tmp/ccoxWTgs.o(.text+0x98): In function `main':
: undefined reference to `mysql_real_query'
/tmp/ccoxWTgs.o(.text+0xb2): In function `main':
: undefined reference to `mysql_error'
/tmp/ccoxWTgs.o(.text+0xe0): In function `main':
: undefined reference to `mysql_use_result'
/tmp/ccoxWTgs.o(.text+0xf8): In function `main':
: undefined reference to `mysql_field_count'
/tmp/ccoxWTgs.o(.text+0x10d): In function `main':
: undefined reference to `mysql_fetch_row'
/tmp/ccoxWTgs.o(.text+0x125): In function `main':
: undefined reference to `mysql_num_fields'
/tmp/ccoxWTgs.o(.text+0x178): In function `main':
: undefined reference to `mysql_close'
collect2: ld returned 1 exit status
---
Странно почему ld не хочит линковать. А также строчка "mysql2.c:5: warning: return type of `main' is not `int'"
При чём тут это? Если я чётко указал "void main(void)"
ПОМОГИТЕ! очень надо :)
За ранее спасибо.
Я не заметил. При компиле выше написанного (с изменением типа функции на `int') вот что вылазит... :
root@ch00r:~/kgrfm# ulimit -Sc unlimited
root@ch00r:~/kgrfm# gcc -o k k.c -lmysqlclient -ggdb
root@ch00r:~/kgrfm# ./k
Segmentation fault (core dumped)
root@ch00r:~/kgrfm# gdb -c core
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux".
Core was generated by `./k'.
Program terminated with signal 11, Segmentation fault.
#0 0x400c8640 in ?? ()
(gdb) inf reg
eax 0x100 256
ecx 0xbfffebc0 -1073747008
edx 0x4005105c 1074073692
ebx 0x40181234 1075319348
esp 0xbfffeb40 0xbfffeb40
ebp 0xbfffeb58 0xbfffeb58
esi 0x54 84
edi 0x4003cc38 1073990712
eip 0x400c8640 0x400c8640
eflags 0x10202 66050
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
fctrl 0x0 0
fstat 0x0 0
ftag 0x0 0
fiseg 0x0 0
fioff 0x0 0
foseg 0x0 0
fooff 0x0 0
---Type <return> to continue, or q <return> to quit---
fop 0x0 0
(gdb) q
root@ch00r:~/kgrfm# gdb
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux".
(gdb) file k
Reading symbols from k...done.
(gdb) run k
Starting program: /root/kgrfm/k k
Program received signal SIGSEGV, Segmentation fault.
0x400c8640 in malloc () from /lib/libc.so.6
(gdb) q
The program is running. Exit anyway? (y or n) y
root@ch00r:~/kgrfm# fuck :(
bash: syntax error near unexpected token `('
root@ch00r:~/kgrfm#
---
Тут уж фиг его знает.
уже лучше. inside09.11.03 13:17 Автор: Eugene Статус: Незарегистрированный пользователь
> уточнение 2 Ktirf: > -llibname подключает не liblibname.a (это статика), а > liblibname.so (-l - ключ для динамической линковки) А какой тогда ключ для статической линковки? ;)
а для статической линковки нет ключа ). gcc -o file file.o staticlibrary.a09.11.03 18:01 Автор: Eugene Статус: Незарегистрированный пользователь Отредактировано 09.11.03 18:08 Количество правок: 2
но - можно линковать и так
gcc -o file file.o dynamiclibrary.so
тогда динамическая библиотека будет использована не по назначению, но результат компиляции может быть и удачным.
а как ты обратишься к функции из library.a извне? ;-)
> а как ты обратишься к функции из library.a извне? ;-) Что-то я не очень понял, в чем проблема... #include <header.h>, после этого -lrary (или library.a, можно и так, и так) при компоновке.
> file.a - всего-лишь собранная ar-ом кучка объектников. Не буду спорить, и что?
> ps: попробуй собрать модуль perl DBD::mysql без mysql-devel > только с пакетом mysql-<version>. а ведь > libmysqlclient.a в нем есть. Где, извините, есть libmysqlclient.a? В DBD::mysql или, может быть, в mysql-<version>? Вообще-то не знаю, как где, но в родных rpm-никах от MySQL libmysqlclient.a находится именно в mysql-devel, там же, где и заголовки.
вобщем-то это не новость ;)10.11.03 01:31 Автор: Eugene Статус: Незарегистрированный пользователь
> #include <header.h>, после > этого -lrary (или library.a, можно и так, и так) при > компоновке.
проблемы нет. просто я утверждаю, что -lmysqlclient подключает именно libmysqlclient.so [именно об этом мы и говорим], а не libmysqlclient.a или тем более libmysqlclient.la
и без -static - подкючает именно динамически.
незнаю, каким образом ты ключем -l подключаешь *.a файлы. ведь после -l линкер ищет библиотеку в /etc/ld.so.cache, а там хранится таблица именно для so-шников, и никак не для *.a.
> > > file.a - всего-лишь собранная ar-ом кучка объектников. > Не буду спорить, и что?
ничего нового. просто "кучку объектников" нельзя подключить динамически. из нее (кучки) нельзя налету вызвать функцию.
> > > только с пакетом mysql-<version>. а ведь > > libmysqlclient.a в нем есть. > Где, извините, есть libmysqlclient.a? В DBD::mysql или, > может быть, в mysql-<version>?
будешь смеяться, но, как я и сказал, именно в mysql-<version> (mysql-3.23.56-pc-linux-i686.tar.gz c mysql.com как пример). хотя - это не правило.
и *.so там нет... но опять-таки - этот не правило, в пакетах для slackware в mysql-<version> есть и *.a, и *.so.
на счет рпм-ов не спорю. но мы не о комплектации пакетов говорим, а о том, что -llibname говорит линкеру линковать с *.so.
> проблемы нет. просто я утверждаю, что -lmysqlclient > подключает именно libmysqlclient.so > [именно об этом мы и говорим], а не libmysqlclient.a или > тем более libmysqlclient.la > и без -static - подкючает именно динамически. Хорошо. Я утверждаю, что подключение libmysqlclient.so в этом случае - это только первая попытка. Если libmysqlclient.so не обнаруживается, делается попытка (статически, естественно) найти по путям из -L и залинковать libmysqlclient.a.
> Вроде нарыл что да как, но проблема, всё равно не > получается, может гуру си пояснят, что да как. Я > относительно не давно начал программить на си. Заметно :) Настоятельно рекомендую читать учебники по C.
> Всё как в мануалах...
> Странно почему ld не хочит линковать. Ничего странного. Все функции, на которые ld жалуется, находятся в библиотеке libmysqlclient.a, которую ты подключить не удосужился. Подключение, как уже указал Eugene, делается указанием при вызове gcc опции -l, в твоем случае -lmysqliclient.
> А также строчка > "mysql2.c:5: warning: return type of `main' is not `int'" > При чём тут это? Если я чётко указал "void main(void)" Ну так тебе компилятор четко и ответил - не надо так делать :) У функции main может быть одна из двух следующих сигнатур:
int main() или
int main(int, const char **) Есть другие варианты, но о них знать не обязательно, и самое главное - main всегда должен возвращать int! Общим правилом является возврат нуля, если все закончилось хорошо, и кода ошибки в противном случае.
Что же касается выделения памяти, то в целом Eugene прав, хотя и неправ в частности: в твоем конкретном случае (с переменной query) все будет нормально работать :) А вообще текстовые строки, конечно, лучше размещать в куче, "если не указано иное", как пишут в договорах. Существуют вполне определенные правила, в каких случаях это не нужно (например, если, как в твоем случае, написать переменная = текстовая строка), но по этому поводу лучше (внимательно) почитать учебник.
Кстати, если тебе ближе Pascal, то почему бы тебе и не писать на нем тогда? Ничто не мешает подключить библиотеку mysqliclient из программы на Паскале.
перед тем как делать
query="select * from test"; выдели память malloc-ом.
если совестный - можешь еще и освободить ее перед завершением.
это основы работы с указателями.
на счет того, почему не линкуется - опять-таки , не вникая в код - подключай библиотеку. например так
-lmysqlclient
попутно посмотри, видна ли она линкеру.
пароль, логин и хост вынеси в какой-то хедер в константы.
ошибки выводи в stderr хотя бы через perror или fprintf
> printf( "Error connecting to database: > %s\n",mysql_error(mysql)); > } > else printf("Connected...\n"); > > query="select * from test"; > > } > printf("\n"); > } > mysql_close(mysql); > } > --- > /tmp/ccoxWTgs.o(.text+0x3c): In function `main': > : undefined reference to `mysql_real_connect' > /tmp/ccoxWTgs.o(.text+0x51): In function `main': > : undefined reference to `mysql_error' > /tmp/ccoxWTgs.o(.text+0x98): In function `main': > : undefined reference to `mysql_real_query'
> malloc только под query? > И зачем, поясни пожалуйста.
под все текстовые данные. да и не только текстовые. под все, что не вмещается в sizeof(unsigned) ;-)
надо отвыкать от паскалевских приемов. в си - char *query
говорит о том, что query - указатель на строку. другими словами - unisigned long значение, которое содержит адрес первого символа строки (char говорит о том, что эта строка состоит из символов, если б там было, например, unsigned long * - тогда при обращении к N-ому символу массива query[N] ты попадал бы не на N байт, а на N*4, так как sizeof(unsigned) == 4 вроде был).
если ты хочешь, что б query указывал на нужную тебе строку - выдели под нее память. маллок выделяет память из кучи и возвращяет тебе адрес участка, который и нужно присвоить указателю.
query = (char *)malloc(STRING_SIZE);
snprintf(query,STRING_SIZE,"%s - format string",your_data);
[ int snprintf(char *str, size_t size, const char *format, ...);
The functions snprintf and vsnprintf do not write more than
size bytes (including the trailing '\0'). If the output was truncated
due to this limit then the return value is the number of characters
(not including the trailing '\0') which would have been written to the
final string if enough space had been available. Thus, a return value
of size or more means that the output was truncated. (See also below
under NOTES.) If an output error is encountered, a negative value is
returned.
]
следи, что б переполнения буфера небыло, ведь неизвестно, что находится за выделенным фрагментом. данные других программ ты не повредишь (режим-то защищенный), а вот свои можешь затереть, если выйдешь за буфер.
в общем случае - делай man function_name
кроме всего прочего есть библиотечка - MyC 04.11.03 17:35 Автор: Eugene Статус: Незарегистрированный пользователь
Cтавишь пакет MySQL-devel (взять его можно из дистрибутива или с сайта MySQL), обнаруживаешь в файловой системе инклудники и библиотеки MySQL, пользуешься :)))