Pro*Cを使ったソースのリンクで
undefined reference to `sqlcxt(void**, unsigned int*, sqlexd*, sqlcxp const*)'
というエラーでハマったのでメモ残しておく。
結論から書くと、今回コンパイルしようとしていたソースはC、C++ソース混在で、その場合はprocでのプリコンパイルはcode=cppでプリコンパイルしないとダメで、それをcode=ansi_cでプリコンパイルしてたのがダメだったというのがリンクエラーの原因。
以下、試した内容。
Pro*Cのバージョン:11.2
環境:CentOS 5.9
コンパイラ:g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
こんなソース作って試してみた。サンプルなので動かないソースなのは気にしない。
#include <sqlca.h> #include <stdio.h> int commit(sql_context *context) { struct sqlca sqlca; sqlca.sqlcode = 0; EXEC SQL CONTEXT USE :*context; EXEC SQL COMMIT; int code = sqlca.sqlcode; if (code != 0) { printf("error %s\n", sqlca.sqlerrm.sqlerrmc); } return(code); } int main() { commit(NULL); }
上記ソースでcode=ansi_cとcode=cppでプリコンパイルしたソースを比較。関数定義がextern "C"{}で囲われているかそうでないかの違いがある。
$ proc iname=sample.pc code=ansi_c include=/usr/include/oracle/11.2/client64 oname=sample_ansi.c Pro*C/C++: Release 11.2.0.3.0 - Production on Thu Mar 21 09:30:06 2013 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. System default option values taken from: /usr/lib/oracle/11.2/client64/lib/precomp/admin/pcscfg.cfg $ proc iname=sample.pc code=cpp include=/usr/include/oracle/11.2/client64 oname=sample_cpp.c Pro*C/C++: Release 11.2.0.3.0 - Production on Thu Mar 21 09:30:14 2013 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. System default option values taken from: /usr/lib/oracle/11.2/client64/lib/precomp/admin/pcscfg.cfg $ diff sample_ansi.c sample_cpp.c 116,123c116,125 < /* SQLLIB Prototypes */ < extern void sqlcxt (void **, unsigned int *, < struct sqlexd *, const struct sqlcxp *); < extern void sqlcx2t(void **, unsigned int *, < struct sqlexd *, const struct sqlcxp *); < extern void sqlbuft(void **, char *); < extern void sqlgs2t(void **, char *); < extern void sqlorat(void **, unsigned int *, void *); --- > // Prototypes > extern "C" { > void sqlcxt (void **, unsigned int *, > struct sqlexd *, const struct sqlcxp *); > void sqlcx2t(void **, unsigned int *, > struct sqlexd *, const struct sqlcxp *); > void sqlbuft(void **, char *); > void sqlgs2t(void **, char *); > void sqlorat(void **, unsigned int *, void *); > } 125c127 < /* Forms Interface */ --- > // Forms Interface 129c131 < extern void sqliem(unsigned char *, signed int *); --- > extern "C" { void sqliem(unsigned char *, signed int *); }
code=ansi_cでプリコンパイルしたソースのコンパイル。
リンク時にsqlcxtのリンクエラー発生。
$ g++ sample_ansi.c -I/usr/include/oracle/11.2/client64 -L/usr/lib/oracle/11.2/client64/lib -lclntsh /tmp/cckOi2dx.o: In function `commit(void**)': sample_ansi.c:(.text+0xa0): undefined reference to `sqlcxt(void**, unsigned int*, sqlexd*, sqlcxp const*)' collect2: ld はステータス 1 で終了しました
code=cppでプリコンパイルしたソースのコンパイル。
コンパイル、リンクともエラーはなし。
$ g++ sample_cpp.c -I/usr/include/oracle/11.2/client64 -L/usr/lib/oracle/11.2/client64/lib -lclntsh $
ということで、C++環境ではcode=cppでプリコンパイルする必要があるということでした。