• ベストアンサー

可変長引数を実現する va系

今、可変長引数をBUFFERにいれて 送る(SSLを使いますが・・・)ことをしていますが、 どうしてもその部分らしいところでwarningがでます。 どうもいまいちva系の取り扱いがわからないので、 アドバイスいただけるとうれしいです。 ****ソース(va系が含まれるところのみ)**** WriteToClient (fmt, va_alist) char *fmt; va_dcl { va_list ap; char * ssl_buf[1024]; va_start (ap); vfprintf (stdout, fmt, ap); va_end (ap); //SSL SSL_write(ssl, ssl_buf, sizeof(ssl_buf) ); } *****コンパイル後のwarningメッセージ**** /usr/local/lib/gcc-lib/i386-pc-solaris2.8/2.95.3/include/stdarg.h:96: warning: ` va_start' redefined /usr/local/lib/gcc-lib/i386-pc-solaris2.8/2.95.3/include/varargs.h:111: warning: this is the location of the previous definition SSLpasschanger.c:216: macro `va_start' used with just one arg わかる方いらっしゃいましたら、よろしくおねがいいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • route156
  • ベストアンサー率85% (93/109)
回答No.4

 ん~つまり WriteToClient 関数を printf のように扱いたいってことですか?  それでしたら、こんな感じだと思います。 void WriteToClient(char* fmt, ...) {  char ssl_buf[1024];  va_list ap;  va_start(ap, fmt);  vsprintf(ssl_buf, fmt, ap);  SSL_write(ssl, ssl_buf, sizeof(ssl_buf)); }  この書き方で良かったのかどうか忘れてしまいましたが、とりあえず ap には fmt の次の引数のアドレスが入るはずです。  ただ、va_ マクロの実装は処理系によってかなり違うと思いますから、やはり自信は無しです。  呼び出し方は printf と同じです。フォーマットも指定してください。 WriteToClient("%s", "500 Username required."); // "全角空白" でインデントしてますのでご注意を…もうご存知でしたね。 // No.1 で関数内に書いた ... は "省略" の意味です。なので 214 ... は必要ないです。引数リストの ... は必要です。 // それから gcc には va_alist や va_dcl というマクロもあったのですね。不勉強でした。No.1 の後半部分は忘れてください。

en_love
質問者

お礼

御礼が遅れてしまってすいません。 おかげさまでなんとか無事できました。 ありがとうございました!!! とても感謝しております!

その他の回答 (3)

  • route156
  • ベストアンサー率85% (93/109)
回答No.3

 すみません。書き忘れました。  warning メッセージについてですが、stdarg.h と varargs.h で定義が重複しているのではないでしょうか。普通はヘッダファイルの中で二重定義を避けるための記述がされているはずですが、とりあえずインクルードファイルは stdarg.h の方だけで試されてみると良いと思います。

en_love
質問者

お礼

丁寧な説明、ありがとうございます! すごく感動してます。 warningはきれいに消えました!(T▽T)うれし~♪ お手数ながら、その後のエラーのことも教えていただけないでしょうか? さっそく一番下に書いていただいたもの(↓)でやってみたのですが、 208 void WriteToClient(char* fmt, va_list va_dcl) 209 { 210 char ssl_buf[1024]; 211 212 vsprintf(ssl_buf, fmt, va_dcl); 213 SSL_write(ssl, ssl_buf, sizeof(ssl_buf)); 214 ... 215 } 関数を呼び出すとき、引数が少ないというメッセージが帰ってきました。 342:too few arguments to function `WriteToClient' 呼び出すときは、 342 WriteToClient ("500 Username required."); のように呼び出しているのですが・・・ printfと同じように記述すればよい、と思っていたのですが・・・ちがいますかね? どうしたらよいでしょうか? まだプログラミング初心者なもので・・・すいません(^-^; お願いします。

noname#30727
noname#30727
回答No.2

WriteToClient そのものが、可変引数関数になるのなら、 route156 さんの書かれた、function のように、 void WriteToClient(char *fmt, ...) とします。まぎらわしいのですが、2つ目の引数はドットを3つ連続で書いてください。

  • route156
  • ベストアンサー率85% (93/109)
回答No.1

 うろ覚えで自信は無いのですが、va_start, va_arg, va_end は可変長引数を一つずつ取り出す場合に使ったと思います。 void function(char* fmt, ...) {  va_list ap;  int param1;  char* param2;  va_start(ap, fmt);  param1 = va_arg(ap, int);  param2 = va_arg(ap, char*);  ...  va_end(ap); }  ただ、ご質問では vfprintf を使われているようですので、これは引数として va_list をそのまま受け取りますから、va_start 等は必要ないと思います。 void WriteToClient(char* fmt, va_list va_dcl) {  ...  vfprintf(stdout, fmt, va_dcl);  ... }  老婆心ながら WriteToClient の引数を ssl_buf にセットするのでしたら、次のようになるのでは? 他の部分がわからないので推測ですが。 void WriteToClient(char* fmt, va_list va_dcl) {  char ssl_buf[1024];  vsprintf(ssl_buf, fmt, va_dcl);  SSL_write(ssl, ssl_buf, sizeof(ssl_buf));  ... }  それから、スタック上のバッファを使う時は、オーバーフローに留意された方が良いと思います。  以上、確認はしていないので間違いがあるかもしれません。その点はお許しを。

関連するQ&A

  • Solaris10でmakeがこける

    postfixをインストールしようと make makefiles CC=gcc してから makeしたのですが、 /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/sys/types.h:27:31: sys/feature_tests.h: No such file or directory isa_defs.h: No such file or directory machtypes.h: No such file or directory int_types.h: No such file or directory In file included from sys_defs.h:335,from alldig.c:29: /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/sys/types.h:68: error:syntax error before "int32_t" syntax error before "uint32_t" "int32_t" "uint32_t" "int32_t" "uint32_t" "offset_t" (中略) /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/sys/types.h:622:24: sys/select.h: No such file or directory In file included from /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/limits.h:11,from sys_defs.h:1347,from alldig.c:29: /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/syslimits.h:27:31: sys/feature_tests.h: No such file or directory isa_defs.h: No such file or directory /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/syslimits.h:29:28: iso/limits_iso.h: No such file or directory /usr/local/lib/gcc-lib/i386-pc-solaris2.10/3.3.6/include/syslimits.h:41:28: sys/int_limits.h: No such file or directory alldig.c:30:19: ctype.h: No such file or directory (省略しているところあります) と出てmakeできません。 見つかっていないファイル類がSolaris開発ツールっぽいのしかわからず、どうやって入手すればいいかがわかりません。 SMTP-AUTH対応できればそれでいいのでpkgadd対応版みたいなので代用も可能です。 わかる方、お願いします

  • Net-SNMPでのmake時のエラーについて

    はじめまして。kyosyouと申します。 Solaris(SunOS5.9)でNet-SNMPを使おうとしておりますが、 make時に下記エラーがでて頓挫しております。 google等で調べてみたのですが、類似事象が見つからず、ご質問させていただきます。 making all in /opt/net-snmp/net-snmp-5.4/snmplib make[1]: Entering directory `/opt/net-snmp/net-snmp-5.4/snmplib' /bin/sh ../libtool --mode=compile gcc -I../include -I. -I../snmplib -g -O2 -Dsolaris2=solaris2 -c -o snmp_client.lo snmp_client.c gcc -I../include -I. -I../snmplib -g -O2 -Dsolaris2=solaris2 -c snmp_client.c -fPIC -DPIC -o .libs/snmp_client.o In file included from snmp_client.c:73: /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/sys/param.h:181: warning: `NBBY' redefined /usr/include/sys/select.h:59: warning: this is the location of the previous definition In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/time.h:91, from /usr/include/sys/time.h:419, from /usr/include/sys/select.h:20, from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/sys/types.h:284, from /usr/include/sys/wait.h:20, from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/stdlib.h:17, from snmp_client.c:47: /usr/include/sys/siginfo.h:74: parse error before `pthread_attr_t' /usr/include/sys/siginfo.h:74: warning: no semicolon at end of struct or union /usr/include/sys/siginfo.h:76: parse error before `}' In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/time.h:91, from /usr/include/sys/time.h:419, from /usr/include/sys/select.h:20, from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/sys/types.h:284, from /usr/include/sys/wait.h:20, from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/stdlib.h:17, from snmp_client.c:47: /usr/include/sys/siginfo.h:284: parse error before `int32_t' /usr/include/sys/siginfo.h:284: warning: no semicolon at end of struct or union /usr/include/sys/siginfo.h:284: warning: no semicolon at end of struct or union /usr/include/sys/siginfo.h:286: parse error before `}' /usr/include/sys/siginfo.h:286: warning: data definition has no type or storage class /usr/include/sys/siginfo.h:288: parse error before `}' /usr/include/sys/siginfo.h:288: warning: data definition has no type or storage class /usr/include/sys/siginfo.h:415: parse error before `int32_t' /usr/include/sys/siginfo.h:415: warning: no semicolon at end of struct or union /usr/include/sys/siginfo.h:415: warning: no semicolon at end of struct or union /usr/include/sys/siginfo.h:416: conflicting types for `__rctl' /usr/include/sys/siginfo.h:285: previous declaration of `__rctl' /usr/include/sys/siginfo.h:418: parse error before `}' /usr/include/sys/siginfo.h:418: warning: data definition has no type or storage class /usr/include/sys/siginfo.h:420: parse error before `}' /usr/include/sys/siginfo.h:420: warning: data definition has no type or storage class /usr/include/sys/siginfo.h:424: parse error before `k_siginfo_t' /usr/include/sys/siginfo.h:424: warning: no semicolon at end of struct or union /usr/include/sys/siginfo.h:428: parse error before `}' /usr/include/sys/siginfo.h:428: warning: data definition has no type or storage class In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/include/stdlib.h:17, from snmp_client.c:47: /usr/include/sys/wait.h:90: parse error before `siginfo_t' make[1]: *** [snmp_client.lo] Error 1 make[1]: Leaving directory `/opt/net-snmp/net-snmp-5.4/snmplib' make: *** [subdirs] Error 1 お分かりの方がいらっしゃいましたらよろしくお願い致します。

  • [C++/CLI]可変個引数について

    visual studio 2005を使用し、C++で作ったクラスをVBで呼び出せるようにするため、C++でラッパクラスを作成中です。 ネイティブコードで可変個の引数を表すには、 Test(PSTR str, ...){ char ch[1024]; va_list ap; va_start(ap, str); wvsprintf( ch, str, ap ); va_end(ap);       ・       ・       ・ } のようにすればOKだったのですが、マネージコードで可変個の引数を使用するにはどうすれば良いのでしょうか。「ParamArray」というキーワードを使うのでしょうか? また、ラッパクラスではないクラスの可変個引数を使用しているメソッドで、 「warning C4793: 'vararg' : 関数 'DWORD CTest::Log(PSTR,...)' 用にネイティブ コードの生成が発生します」 というワーニングがでています。これは無視しても大丈夫なのでしょうか? 申し訳ございませんが、分かる方がいましたら回答をお願いします。

  • 可変長引数の扱い

     以下のプログラムが、 Hello,world. Hello, という出力しかしません。どうしてでしょう?  もしこういったことはcでは無理なのだとすれば、printfやsyslogなどのフォーマット指定のある出力関数のラッパーを書く他のいい方法があるんでしょうか? #include <stdio.h> #include <stdarg.h> #include <stdlib.h> void messout(const char *format, ...); int main(void) {   char *str = "world.";   printf("Hello,%s\n", str);   messout("Hello,%s\n", str);   exit(0); } void messout(const char *format, ...) {   va_list list;   va_start(list, format);   printf(format, list);   va_end(list); }

  • gccやg++がGNU製かどうかの確認法は?

    初心者質問で失礼致します。 各UNIX上でgccやg++がGNU製のものかどうかは何処で確認できるのでしょうか? % gcc -v Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.3/specs gcc version 2.95.3 20010315 (release) % g++ -v Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95.3/specs gcc version 2.95.3 20010315 (release) となりましたがGNU製なら"GNU"と表示されるのでしょうか?

  • gccコンパイル時のエラーメッセージを説明してください。

    下に書いてあるプログラムをコンパイルしたら、更にその下に書いてあるようなエラーメッセージがでました。何を直せといっているのかいまいちよく分からないので解説してください。 そもそもgccのコンパイルに失敗しているってことなのかなとも思いましたが、gccはネットからゲットしてきたパッケージなので、なんとも確証がもてません。 プログラム #include<string.h> char * Basename(char *pathname) { char *cp; if(cp = strrchr(pathname,'/')) return cp + 1; return pathname; } メッセージ Undefined first referenced symbol in file main /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.2/crt1.o ld: fatal: Symbol referencing errors. No output written to a.out collect2: ld returned 1 exit status

  • GDモジュールのインストールエラー

    RedHat ES でGDgraphモジュールを使用するために GDモジュールをインストールしたところ、下記のようなエラーになりました。 gcc -c -I/usr/local/include -I/usr/local/include/gd -D_REENTRANT -D_GNU_SOURCE -DTHREADS_ HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FIL E_OFFSET_BITS=64 -I/usr/include/gdbm -O2 -g -pipe -march=i386 -mcpu=i686 -DVERSION=\"2.11\" -DXS_VERSION=\"2.11\" -fPIC "-I/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE" GD .c Running Mkbootstrap for GD () chmod 644 GD.bs rm -f blib/arch/auto/GD/GD.so LD_RUN_PATH="/usr/local/lib:/usr/lib:/lib" gcc -shared -L/usr/local/lib GD.o -o blib/arch/auto/GD/GD.so -L/usr/lib/X11 -L/usr/X11R6/lib -L/usr/local/lib -lgd -lpng -lz -lm/usr/bin/ld: cannot find -lpng collect2: ld はステータス 1 で終了しました make: *** [blib/arch/auto/GD/GD.so] エラー 1 freetype2 gdライブラリ PG.pm GDTextUtile GD::Graph   はインストール完了しましたが gdのインストールだけが何度やっても失敗します。 何のモジュールが足りないのか教えていただきたいです。 よろしくお願いいたします。

  • TunesBrowserのmakeで失敗します

    redhat9,kernel-2.4.20-8,gcc-3.2.2-5で利用してます。 TunesBrowser(http://crazney.net/programs/itunes/tunesbrowser.html)のmake時に以下エラーで失敗します。 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../libglade-2.0.so: undefined reference to `g_return_if_fail_warning' collect2: ld returned 1 exit status make[1]: *** [tunesbrowser] エラー 1 make: *** [all] エラー 2 Makefile中にはlibglade-2.0を含む項目は以下のようなものがあります。 (中略) GLADE_CFLAGS = -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 -I/usr/include/libxml2 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/X11R6/include -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include GLADE_LIBS = -Wl,--export-dynamic -L/usr/X11R6/lib -lglade-2.0 -lgtk-x11-2.0 -lxml2 -lz -lgdk-x11-2.0 -lXrandr -lXi -lXinerama -lXext -latk-1.0 -lgdk_pixbuf-2.0 -lm -lXcursor -lpangoxft-1.0 -lXft -lfreetype -lXrender -lfontconfig -lpangox-1.0 -lX11 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 (中略) TB_CFLAGS = -I/usr/local/include -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 -I/usr/include/libxml2 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/X11R6/include -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include (省略) またlibglade-2.0.soは /usr/lib/libglade-2.0.so にあります。 色々調べてみたところundefined referenceのエラーの時はリンクが出来ていないのが原因のようですが、リンクのさせ方が分からないので、分かる人教えてください。

  • va_list型について

    あるC言語のソースを見ていたら、va_list型の引數を持つ函數がありました。 そのソースは複雜なので、質問するために以下のソースを作りました。 (ですから、このプログラムはじつよう性もないし、無意味なこともしています。) #include <stdio.h> #include <stdarg.h> int sum_func1(int sw1, va_list ap1) { int sum1 = 0; va_start(ap1, sw1); sum1 += va_arg(ap1,int); sum1 += va_arg(ap1,int); va_end(ap1); return(sum1); } int sum_func0(int sw0, ...) { int sum0; va_list ap0; int a0, b0; va_start(ap0, sw0); a0=va_arg(ap0, int); b0=va_arg(ap0, int); printf("sum_func0です。これから%dと%dを足します。\n", a0, b0); sum0 = sum_func1(sw0, ap0); va_end(ap0); return(sum0); } int main(void) { printf("1 + 2 = %d\n", sum_func0(0,1,2)); return 0; } やっていることは、結局のところ、1と2を足してその結果を表示しているだけです。 このプログラムは動かすことはできますが、表示される足し算の結果がおかしいです。 sum_func0の中で 1(a0)と2(b0)は既にva_argを使って取得しています。 その後、sum_func1の中で、再び この1と2を取得しようとしているのですが、 このようなことは可能でしょうか。 可能ならば、どのように修整すればよいのでしょうか。 これが可能か否かが元のソースの讀み方に影響するのです。 最初に述べたように、va_list型の引數を持つ函數についての質問なので、 va_list型の引數を使わないような修整方法ですと、 期待するものではありません。

  • Openldapインストールmakeでエラー

    Solaris10にOpenldapのインストールがうまく行きません。 make時でエラーになります。 色々、Googleで調べてしているのですが結局うまくいきませんでした。 教えていた頂けたら幸いです。 事前にインストールしたソフト BerkeleyDB4.7.25 openssl0.98l cyrus-sasl-2.1.21 cd openldap-2.4.16 CPPFLAGS="-I/usr/local/BerkeleyDB.4.7/include" LDFLAGS="-L/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.7/lib" ./configure make depend make (cd .libs && rm -f libldap.la && ln -s ../libldap.la libldap.la) gcc -g -O2 -I../../include -I../../include -I/usr/local/BerkeleyDB.4.7/include -c -o apitest.o apitest.c /bin/sh ../../libtool --mode=link gcc -static -g -O2 -L/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.7/lib -o apitest apitest.o libldap.la ../../libraries/liblber/liblber.la ../../libraries/liblutil/liblutil.a -lsasl2 -lgss -lssl -lcrypto -lresolv -lgen -lnsl -lsocket gcc -g -O2 -o apitest apitest.o -L/usr/local/BerkeleyDB.4.7/lib ./.libs/libldap.a /work/src/openldap-2.4.16/libraries/liblber/.libs/liblber.a -L/usr/local/lib:-L/usr/local/ssl/lib:-L/usr/sfw/lib:-L/usr/lib:-L/opt/sfw/lib:-L/usr/ccs/lib:-L/usr/local/BerkeleyDB4.7/lib ../../libraries/liblber/.libs/liblber.a ../../libraries/liblutil/liblutil.a /usr/local/lib/libsasl2.so -ldl -lgss -lssl -lcrypto -lresolv -lgen -lnsl -lsocket -R/usr/local/lib -R/usr/local/lib -R/usr/local/BerkeleyDB.4.7/lib Undefined first referenced symbol in file BIO_set_flags ./.libs/libldap.a(tls_o.o) BIO_clear_flags ./.libs/libldap.a(tls_o.o) SSL_CTX_set_info_callback ./.libs/libldap.a(tls_o.o) ld: fatal: Symbol referencing errors. No output written to apitest collect2: ld returned 1 exit status make[2]: *** [apitest] エラー 1 make[2]: ディレクトリ `/work/src/openldap-2.4.16/libraries/libldap' から出ます make[1]: *** [all-common] エラー 1 make[1]: ディレクトリ `/work/src/openldap-2.4.16/libraries' から出ます make: *** [all-common] エラー 1 勉強不足で申し訳ありませんが、よろしくお願いします。