• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ライブラリ作成時のグローバル変数の対応(C言語))

C言語でのライブラリ作成時のグローバル変数対応

このQ&Aのポイント
  • C言語でライブラリを作成する際に、ライブラリ内でのみ使用するグローバル変数や関数を実現する方法はあるのか
  • Windows7とVisualC++2010を使用して開発を行う場合、C++でプログラミングすることもできるが、C言語での実現も可能か
  • あるサイトでは、特殊なマクロを使用することでC言語でのライブラリ作成時にグローバル変数を実現する方法が紹介されているが、他にも方法はないのか

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

  • ベストアンサー
回答No.2

スレッドセーフを意識する場合、ライブラリ内でグローバル変数を持つ事は許されません。 「一連の呼び出しの中で、グローバルなスコープが必要」なのであれば、fopen関数でやっているように「開始関数で一意のハンドラを返し、一意のハンドラを指定して一連の呼び出しを行ってもらい、終了処理で一意のハンドラを開放する」と言うような書き方をしないといけません。 fopenが「グローバル変数で、次に使える、空いているハンドラの番号を持っている」と言う実装があったとします。 もし、メインのスレッドでfopenが3番のハンドラを返そうと準備している真っ最中(fopenから、まだ帰って来てない状態)に、サブのスレッドがfopenを呼び出して3番のハンドラを受け取ったら、どうなると思いますか? メインのスレッドも、サブのスレッドも、どっちも「3番のハンドラ」を受け取ります。 メインとサブで異なるファイルをオープンしているのに、ライブラリがグローバル変数で「次の空きは3番」なんて情報を持っていた所為で、両方とも「3番」を受け取ってしまったのです。 もちろん、実際のfopenは「マルチスレッドであっても一意」になっているヒープ領域を用いて「スレッドが切り替わっても大丈夫」な作り(つまり、スレッドセーフ)になっているので、こういう事は起きません。 ライブラリ内にグローバル変数を作ると「マルチスレッド禁止」になっちゃうので、スレッドセーフにするなら、グローバル変数は作ってはいけません。ライブラリ内の変数は、必ず「外にスコープを持たないstatic変数」にしないといけません。

cyacya2000
質問者

お礼

スレッドセーフについては完全に考えから抜けていました。 やはり、グローバル変数は作らないようにします。 ありがとうございました。

その他の回答 (2)

回答No.3

>ライブラリ使用者がライブラリ内でしか使用しないグローバル関数やグローバル変数と同じ名前を使用しても問題ないレベルを希望しています。 C言語ではそれは不可能。言語の仕様上、そういう事は「出来ない仕様」になっています。 例えば、fopenを使うと、fopen等のファイル入出力関数群がグローバルに扱う「_iobuf」と言う変数がリンクされます。 当然、ユーザーは「_iobuf」と言う名前のグローバル変数を作る事は許されません。「同じ名前は許されない」からです。 そのため、Cの標準ライブラリでは、グローバル変数やシンボリック定数は「アンダースコアから始まる」と決められ「ユーザーはアンダースコアから始まる変数や定数を作ってはならない」と決めました。 とうぜん、そうした理由は「ライブラリ内でしか使用しないグローバル関数やグローバル変数と同じ名前は、ユーザーは使用出来なくなる」からです。 なので、最初から「ユーザーは使うな」と決めたのです。 「使うな」と禁止しておけば、バッティングする事は有り得ません。

cyacya2000
質問者

お礼

早速のご回答ありがとうございます。 おっしゃっている意味はわかるのですが、 VC++2010のオプションなどで救える手段があれば教えていただきたいのですが。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「ある程度」で妥協していいなら「外部から #include するヘッダ」と「内部からのみ #include するヘッダ」に分けるのが簡単.

cyacya2000
質問者

お礼

早速のご回答ありがとうございます。 公開しないということなら、ヘッダを分けることでもある程度は実現できますが、 ライブラリ使用者がライブラリ内でしか使用しないグローバル関数やグローバル変数と同じ名前を使用しても問題ないレベルを希望しています。

関連するQ&A

専門家に質問してみよう