none
Cの構造体について教えてください RRS feed

  • 質問

  • 皆様はじめまして。

    普段はCOBOL言語を扱っているのですが、わけあってCサブルーチンをDLLにリンク

    する作業を行っています。

    2003.NETでは問題なくビルドできたのですが2005では以下のエラーが発生します。

    以下ログより抜粋

    コンパイルしています...
    sub.c
    mswinsub.c
    filetbl.c
    direct.c
    d:\acugt\lib\direct.c(85) : error C2079: 'LIBDIRECT' が 未定義の struct 'LIBDIRECT' で使用しています。
    d:\acugt\lib\direct.c(85) : error C2078: 初期化子の数が多すぎます。
    d:\acugt\lib\direct.c(85) : error C2065: 'FUNC' : 定義されていない識別子です。
    d:\acugt\lib\direct.c(85) : error C2061: 構文エラー : 識別子 'TCPCommOpen'
    d:\acugt\lib\direct.c(86) : error C2059: 構文エラー : ','
    d:\acugt\lib\direct.c(87) : error C2059: 構文エラー : ','
    d:\acugt\lib\direct.c(88) : error C2059: 構文エラー : ','
    d:\acugt\lib\direct.c(90) : error C2059: 構文エラー : '}'

    抜粋以上。

    direct.cには以下のようなコーディングを行っています。

    以下ソースより抜粋

    #include "tcpcom.h"

    struct DIRECTTABLE LIBDIRECT[] = {
     { "TCPCOMOPEN",FUNC TCPComOpen, C_int },
     { "TCPCOMCLOSES",FUNC TCPComClose, C_int },
     { "TCPCOMSENDS",FUNC TCPComSend, C_int },
     { "TCPCOMRECV",FUNC TCPComRecv, C_int },
     { NULL,   NULL,  0 }
     };

    抜粋以上。

    この現象の回避方法をご存知のかた、なにとぞご教授願います。

    2006年7月28日 2:58

すべての返信

  •  C初心者 さんからの引用

    { "TCPCOMOPEN",FUNC TCPComOpen, C_int },
     { "TCPCOMCLOSES",FUNC TCPComClose, C_int },
     { "TCPCOMSENDS",FUNC TCPComSend, C_int },
     { "TCPCOMRECV",FUNC TCPComRecv, C_int },
     { NULL,   NULL,  0 }
     }; 

    struct DIRECTTABLE LIBDIRECTがどんな構造体か不明ですが、
    FUNC TCPComOpen のように、空白を入れると、ひとつのトークンとして認識されません。
    (FUNCがどういう値なのか不明なので間違っているか知れませんが)

    もっと具体的にどうすればよいかを聞きたいのであるならば、最低限抜粋した部分だけで
    おなじエラーを出せるようなソースを提示してください。
    (構造体宣言も不明。FUNCって?TCPComOpenらはなに?C_int って?)


    単に、インクルードファイルが抜けているだけだったりして。。。
    もしくは、cppでコンパイルしないといけないとか。

    2006年7月28日 3:51
  • 蒼の洞窟さんご指摘ありがとうございます。

    ”struct DIRECTTABLE LIBDIRECT”が記述されていたのが”direct.c”というのですが、

    TCPCom 関数群の定義ということで以下を”TCPCom.h”として

    宣言しています。以下が内容です。


    // C 言語(Not C++)処理系での呼び出しのための extern 宣言
    #ifdef __cplusplus
    extern "C" {
    #endif /* __cplusplus */

     TCPComOpen(LPSTR, int);
     TCPComClose(void);
     TCPComSend(LPSTR, int);
     TCPComRecv(LPSTR, int, int);
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */

    #endif

    // End of File "TCPCom.h"

     

    そして別の定義ファイル”sub.h”があり、direct、funcの定義をしています。

    以下”sub.h”より抜粋。

    struct DIRECTTABLE {
     char *name;   /* subroutine name */
     int (*routine)();  /* pointer to routine */
     short return_type;  /* routine's return type */
    };

    #define FUNC (int(*)()) /* useful cast for DIRECTTABLE entries */

    抜粋以上。

    そして”sub.c”として以下の記述があります。

    ”sub.c”より抜粋。

    #include <stdio.h>
    #ifdef _WINDOWS
    #include <windows.h>
    #endif /* _WINDOWS */

    #include "sub.h"

    /* Include the direct 'C' interface */
    #include "direct.c"

    抜粋以上。

    以上が関連する定義です。情報として足りるかどうかわかりませんが、

    宜しくお願いします。

     

    2006年7月31日 0:58
  • ん~あんまりよくわかりませんが、エラーを見ると "direct.c" をコンパイルするときにエラーが出ているので、
    direct.c で sub.h と tcpcom.h をインクルードしてみてはどうでしょうか?
    (その代わりに sub.c からは sub.h と tcpcom.h のインクルードを消す)
    2006年7月31日 2:07
  •  C初心者 さんからの引用

    2003.NETでは問題なくビルドできたのですが2005では以下のエラーが発生します。

    ソースをよく見ないで返信しますが、C++としてコンパイルされているのでは?

    IDEを使っている場合に限定されますが、2003は拡張子をみてCかC++かを切り替えるのがデフォルトで、2005は常にC++。

    2005と2003で文法的な違いはあまりないはずです。同じC95だし・・・。

    2006年7月31日 4:44
  •  C初心者 さんからの引用

    struct DIRECTTABLE LIBDIRECT[] = {
     { "TCPCOMOPEN",FUNC TCPComOpen, C_int },
     { "TCPCOMCLOSES",FUNC TCPComClose, C_int },
     { "TCPCOMSENDS",FUNC TCPComSend, C_int },
     { "TCPCOMRECV",FUNC TCPComRecv, C_int },
     { NULL,   NULL,  0 }
     };

    もしかして二番目の値は(FUNC)TCPComOpenとかキャストしたかったのではないかと
    思っていますが、そういう解釈でいいんですかねぇ?
    いずれにしてもエラーが再現出来うる最低限のソースを公開しないとなぁ。

    ふと気がついた事を追記。
    もしかしてdirect.cなるファイルをプロジェクトに登録していたりしませんかね。
    どうも話を読んでいるとdirect.cなるファイルは拡張子がcであるにもかかわらず、
    インクルードして使わないと駄目なんじゃないかと言う気がしてます。
    プロジェクトにソース登録していると無条件にコンパイル対象になってしまうので
    直接コンパイルしてほしくないのであれば、プロジェクトに登録しては駄目です。
    というか、こういう使い方をするならヘッダーファイルにするべきかと思います。
    それならコンパイル対象になりません。

    あと、多分仕方なくやっているのだと思いますけれど、
    C言語の知識がきちんと無いままに外に出すプログラミングをしているのであれば、
    テストをよっぽどきちんとしないとかなり危険ではと思います。
    実際の話、C言語のプログラムで動いているからOKと言うのは結構危ないです。
    ポインタ絡みの部分は一見動いていて爆弾抱えているケースも少なからずありますし。
    (特にプログラミングしている人がきちんとC言語の知識を持っていないと危ないです)

    2006年8月3日 6:45
  • 蒼の洞窟さん、konumaさん、PATIOさん皆様回答ありがとうございます。

    結局、リンク元のDLLの制限で、2003.NET以外は保障しないという通知があり

    2005での作業は取りやめとなりました。

    皆様有益な助言をどうもありがとうございました。

     

    2006年8月16日 9:51