MySQLをC言語から使う

PerlやPHPからではDBIや内蔵ライブラリ任せで良いのですが、C言語では直接MySQLのライブラリを使用します。

まずは、必要なヘッダやライブラリがどこにあるかを調べる。
# find / -name mysql.h
/usr/local/src/mysql-5.0.18/include/mysql.h
/usr/local/mysql/include/mysql/mysql.h

# find / -name libmysqlclient.so
/usr/local/src/mysql-5.0.18/libmysql/.libs/libmysqlclient.so
/usr/local/mysql/lib/mysql/libmysqlclient.so

# find / -name libmysqlclient.a
/usr/local/src/mysql-5.0.18/libmysql/.libs/libmysqlclient.a
/usr/local/mysql/lib/mysql/libmysqlclient.a

コンパイル・リンク時に-Iや-Lで指定が必要になります。
# gcc -c -I /usr/local/mysql/include/mysql/ myclient.c
# gcc -o myclient -L /usr/local/mysql/lib/mysql/ -l mysqlclient

一気にやるならこっち
# gcc -o myclient
-I /usr/local/mysql/include/mysql/
-L /usr/local/mysql/lib/mysql/
-l mysqlclient
myclient.c

実際のプログラムに関してはメルマガで紹介しますが、Linuxの場合出来上がったプログラムを使用する際に/usr/local/mysql/lib/mysql/をldconfigで登録しないとだめだったので動的リンクだったかも。
FreeBSDにも同じコマンドがあるのでメルマガ発行前にもう一度検証してみます。

デバッグ完了

UNIX版から開発しているから、次にWindowsで動かす時のデバッグに時間が掛かった。原因はFD_SETSIZE絡み。UNIXだとFD_SETSIZEのサイズは1024で以下のようにディスクリプタが振られた。

0…標準入力
1…標準出力
2…標準エラー出力
3…ソケットサーバー
4…クライアント1(telnet)
5…クライアント2(telnet)

この時点では数の少ないほうからディスクリプタが振られ1024には遠く及ばないので特に問題ではない。

これがWindowsだとコマンドプロンプトから起動した場合

1956…ソケットサーバー
1928…クライアント1(telnet)
1912…クライアント2(telnet)

直接実行ファイルをダブルクリックして起動した場合でも、

96…ソケットサーバー
124…クライアント1(telnet)
140…クライアント2(telnet)

といった感じで肝心のFD_SETSIZEは64で定義されている為、そのままでは役に立たないどころかオーバーフローを起こしてサーバーが落ちてしまっていた。結局Windowsの場合はFD_SETSIZEを2048に再定義するという方法で逃げた。正直ココまでばらついているとループ回数が増える分不利な気がする。

この時点でチョットの変更でFLASHクライアント用になれるチャットサーバーができました。サーバー自身はデータの中身について全く検査はしてないのとバッファは固定値なので大量にデータを送ると最大値以降の文字は削除されてしまうくらいです。

ソースのダウンロードはこちら(EUC)
socket_server_select