C CodでCコードをスクリプトのように扱うPrograming Bible

CまたはC++で書かれたコードが既に存在し、その機能の一部をプロトタイプとしてWebに公開したいという場合には、C言語をスクリプティング言語のように扱うことを可能とする「C Cod」が最適だ。

» 2008年11月26日 00時00分 公開
[Ben Martin,SourceForge.JP Magazine]
SourceForge.JP Magazine

 C Codは、C、C++、またはObjective-Cコンパイラのフロントエンドとして、C言語をスクリプティング言語のように扱うことを可能とするものである。C Codには、C Server Pagesが付属している。C Server Pagesは、WebアプリケーションをCまたはC++で記述し、それをオンデマンドで自動的にコンパイルできるようCGIをサポートする。

 Ubuntu、Fedora、openSUSE用のC Codパッケージは存在しない。今回は、64ビットのFedora 9マシン上でバージョン1.2.8のソースをビルドした。コンパイル中に小さな問題が生じたが、以下に示すように、CFLAGSにposition-independent code(PIC)のオプションを加えることで解決した。PICコードは、メモリの別の場所にロードできるという利点がある。これは、共有ライブラリのコードをコンパイルする場合には好都合である。複数のライブラリが同じアドレスを使用しないように、それらを移動させることができるためだ。


$ tar xzvf /.../ccod-1.2.8.tar.gz
$ cd ./ccod-*/
$ ./configure
$ make
/usr/bin/ld: csp.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
csp.o: could not read symbols: Bad value
$ vi Makefile
PACKAG = ccod-1.2.8
LFLAGS = -shared -Wl,-soname,libcsp.so
CFLAGS = -O2 -fPIC
LIBSTA = *.a
$ make clean
$ make
$ sudo make install

 最初にccodを使用しようとしたとき、以下のようにSegmentation faultが生じた。


$ cat main1.c
#!/usr/bin/ccod
#pragma CCOD:script no
int main( int argc, char** argv )
{
    printf("hi there\n");
    return 0;
}
$ chmod +x main1.c
$ ./main1.c
Segmentation fault

 調べてみると、cksum()関数が原因であることが分かった。試行の結果、変数sのサイズを以下のように変更すると問題が修復された(少なくともクラッシュはしなくなった)。


$ gdb /usr/bin/ccod
(gdb) r main1.c
...
(gdb) bt
#0  0x0000000000404554 in cksum (path=0x10f3390 "/home/ben/testing/ccod/hello-world.c") at ccod.c:1306
#1  0x000000000040441b in get_sourcesum () at ccod.c:1203
#2  0x0000000000409605 in main (in_argc=2, in_argv=0x7fff6008bcd8) at ccod.c:3398
(gdb) q
$ vi /home/ben/testing/ccod/hello-world.c
...
static unsigned long
cksum(const unsigned char *path)
{
//  register unsigned long  i, c, s = 0;
    register unsigned long  i, c = 0;
    int s = 0;
...
... ccodを再コンパイル・再インストール ...
$ ./main1.c
hi there

 先ほどの例では、ソースコードをできるだけ標準のCファイルに近い形のままにしてccodを使用した。単一ファイルからなる簡単なプログラムであれば、ソースコードの上に2行追加するだけで、ccodを使用できる。ccodのWebサイトにあるサンプルのほとんどは、PHPに倣って定義された、混在モードのC構文を用いている。例えば以下の例に示すように、main()関数は存在せず、


$ cat ./main2.c
#!/usr/bin/ccod
hi there
<?
    printf("and more\n");
    return 0;
?>
$ chmod +x ./main2.c
$ ./main2.c
hi there
and more

 この構文は、提供されるC Server Pagesインタフェースを用いたWebプログラミングにccodを使用する場合に適している。ドキュメントページには、C Server Pagesを用いたCGIプログラミングをかなり容易にしてくれる、ちょっとした関数の集合が提供されている。セッション処理、クッキー、フォーム、クエリ文字列へのアクセス、リダイレクトなど、Webプログラミングに必要となる関数が、C Server Pageアプリケーション向けの一般的なC関数としてすべて提供されている。

 最初に示した例では、「#pragma CCOD:script」を用いて、ccodがCソースファイルを扱う方法を指定している。同プロジェクトでは、このようなpragmaが10種類ほど提供されており、使用するコンパイラ、コンパイラに指定するフラグ、プログラムにリンクするそのほかのライブラリ、C Server Pageプログラム特有のオプション数種を指定可能だ。

 ccodはコンパイル済みのバイナリをキャッシュするため、実行の度にソースコードがコンパイルされるわけではない。もちろん、今回わたしがcksum関数に加えたちょっとした変更は、しっかりとテストしたわけではないので、キャッシュ処理を妨害してしまっているかもしれない。問題は、変数sに大きすぎる値が代入されているためであるようだったため、データ型を変更した。別のチェックサム関数をどこかから持ってきて、cksum関数の中身を完全に入れ替えてしまうというのも解決策の1つかもしれない。

 CまたはC++で書かれたコードが既に存在し、その機能の一部をプロトタイプとしてWebに公開したいという場合には、C Codが最適だろう。簡単なコーディング、コンパイル、テスト実行を繰り返す作業でC Codを用いれば、makefileを作成したり、コンパイルプロセスを気にしたりする煩わしさから解放してくれる。

Ben Martin 10年以上にわたってファイルシステムを研究。博士課程を修了し、現在、libferris、ファイルシステム、検索ソリューションを中心にコンサルティングをしている。


Copyright © 2010 OSDN Corporation, All Rights Reserved.

注目のテーマ