ジメジメする梅雨のお悩み、一挙解決! >>

はじめまして。
C++のライブラリ(静的、動的問わず)について
いくつか教えてください。

たとえば、1つのクラスで定義した以下のようなライブラリ
(まずは、静的 or 動的は問いません)があるとします。
class library
{
library();
~library();
public
GetX();
private
 int a;
}

さらに、実行プログラムMain.exeが存在し、このMain.exeは、
上記ライブラリをリンクしているものとします。

このとき、Main.exe内では、libraryをnewすることもなく、
library::GetX();と呼べるわけですが、

(1)コンストラクタはいつ呼ばれているのでしょうか?
(2)(1)に関係しそうですが、Main.exeがマルチスレッドの場合に、
   Main threadとsub threadから呼ぶときに、ライブラリのコンテキスト?インスタンス?は
   同じなのでしょうか?それともスレッドごとに作られるのでしょうか?

ご存知のかたいらっしゃいましたら教えてください。
説明不足があればご指摘ください。宜しくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

>こちらですが、高度なというのはどういう意味でしょうか?


>linux環境でもプロセス間では割り当てメモリが
>異なるような気がいたしますが、
>もし開発環境で異なるということは、
>実際に、開発を始める場合にこのあたりについては
>OSを調べればよいのでしょうか?

基本的にOSの問題ととらえてよいと考えます。
今あるPC用のOSであれば、Win/Linux/Free BSDなど
は皆"高度"であると考えてよいと思います。

組み込み用途だと、直接物理アドレスにアクセスすることも
多いですよね。
むしろ、PCのように論理アドレスが割り振られるほうが
珍しいのでは?
という感じです。
    • good
    • 0
この回答へのお礼

何度もお答えいただきありがとうございます。

直接物理アドレスにアクセスするような場合には、
また変わってくるということですね。
だいぶ理解が深まりました。

お礼日時:2009/05/26 20:24

>static関数はstatic関数だけしか呼べないというのも合っていますでしょうか?



厳密にいうと違いますね。
クラスメンバ関数限定での話であれば
staticメンバ関数は非staticメンバ関数を呼べないので、
static関数しか呼べないという言い方もできます。

ただし、static関数でもクラスに所属しない関数は自由に呼べます。
その意味で、厳密にはクラスのstatic関数は、クラスのstatic関数
しか呼べないわけではありません。

>class内で定義したstatic関数(library::GetX();)とグローバル関数は
>単に名前が違うものと思えばよいのでしょうか?

基本的な扱い方は、クラス名::をつけられたグローバル関数と
考えてもよいと思います。
ただし、あくまでもクラスに所属する以上
アクセス制限(public, protected, private)からは逃れられません。

publicなstaticメンバ関数は
(呼び出す側からすれば)
クラス::をつけて呼ぶことがお約束のグローバル関数と考えてよいと思います。

>たとえば、プロセスA、Bがあり、Aのほうで定義(合っていますか?)した
>static関数Aがあった場合、
>プロセスBからstatic関数Aは呼べるのでしょうか?

また、理解に苦しむのですが....
そもそも、プロセスAとプロセスBはお互い関数コールなどは
”基本的には"できません。
プロセス間通信など、特別な手法が必要です。

私が勝手に想像するに
複数のプロセス間でクラスstatic関数を通じてクラスのメンバ変数を
共有できるのか?

ということがお知りになりたいのではと思います。

具体的にコードを提示しましょう

class c
{
protected:
static int m_Count = 0;
public:
static void Inc() {m_Count++;}
static int GetCount() {return m_Count;}
}

こんなクラス cがあります。
プロセスX内で
c::Inc();
と実行した後
c::GetCount()は1を戻します。
これ以後
プロセスXではc::Inc()を一切呼ばないものとします。

その後、プロセスYで
c::GetCount()
を呼んだら、答えはどうなるか?

初期値のまま0が戻るのか、
それとも
プロセスXの実行結果を反映して
1が戻るのか?

こういうことではないでしょうか?

答えは前者(0)です。
クラスのstaticメンバであっても
プロセス境界を越えて共有することはできません。

ちょっと低レベル(マシン寄りという意味)な話をさせてもらうと
プロセスにはそれぞれ、別々のメモリが割り当てられ、
お互いに、他のプロセスのメモリをアクセスすることは
不可能です。

プロセスXでいうアドレス0x00001234は
物理メモリの0xAAAA1234を指しているかも知れません。

プロセスYでアドレス0x00001234に書き込んでも
物理メモリの0xAAAA1234には(通常)書き込まれません。
なぜなら
プロセスYにはプロセスXが使用するメモリとは重ならない
領域が割り当てられるからです。
プロセスYの0x00001234は物理メモリの
0xBBBB1234
に割り当てられるかもしれません。

ソースコード上では
char* p;
p = 0x00001234;
というコードがプロセスX、Y両者にあれば
*pを通じて情報が共有できそうですが、
(実際、MSDOSなどの時代にはできていました)
Windowsのような”高度な"OSでは不可能です。

それにより
1つのプロセスが誤動作を起こしても
他のプロセスに影響が及ぶ可能性を
(0とはいかないが)低減させているのです。

この回答への補足

とても分かりやすいご説明ありがとうございます。

> 私が勝手に想像するに
> 複数のプロセス間でクラスstatic関数を通じてクラスのメンバ変数を
> 共有できるのか?

こちら、そのとおりです。
クラスstatic関数だけでなく、グローバル関数についても
お聞きしたかったところですが、
プロセス間ではスレッド間とは異なり割り当てられているメモリが
異なるということでアクセスすることはできないということだと思います。

> ソースコード上では
> char* p;
> p = 0x00001234;
> というコードがプロセスX、Y両者にあれば
> *pを通じて情報が共有できそうですが、
> (実際、MSDOSなどの時代にはできていました)
> Windowsのような”高度な"OSでは不可能です。

こちらですが、高度なというのはどういう意味でしょうか?
linux環境でもプロセス間では割り当てメモリが異なるような気がいたしますが、
もし開発環境で異なるということは、
実際に、開発を始める場合にこのあたりについてはOSを調べればよいのでしょうか?
それともプログラミング言語を調べるべきなのでしょうか?
それともコンパイルの設定などで変更できるものなのでしょうか?

補足日時:2009/05/23 11:52
    • good
    • 0

ライブラリとクラスの概念を混同していませんか?


この2つには全く何の関係もありません。
そこを明確にしましょう。

>1つのクラスで定義した以下のようなライブラリ

表現があやしいですが...
1つのクラスだけで構成されるライブラリ
と理解しておきます。

>上記ライブラリ
class library を含むライブラリ
と理解します。

>このとき、Main.exe内では、libraryをnewすることもなく、
>library::GetX();と呼べるわけですが、

えーーーーーーーーーーー
本当ですか?
基本的には無理です。
C++の言語仕様からいって不可能です。

GetX() がstaticなら可能ですが
staticじゃないですよね?

ライブラリでも一般のソースでもそうですが
クラス名::メンバ関数名
の形式でコールできるのは
1)派生クラス内部から基本クラスのメンバを呼ぶ場合
2)static関数を呼ぶ場合

に限定されます。

staticをつけ忘れたという前提で話します。
(違っていたらごめんなさい)

>(1)コンストラクタはいつ呼ばれているのでしょうか?

static関数を呼び出すのにオブジェクトは必要ありません。
(必要ないのでクラス名::の形式で呼べるのです)
コンストラクタが呼ばれなくても動作します。
その代わり、staticメンバ関数からはstaticメンバ変数にしか
アクセスできません。
staticでない”普通の"メンバ変数はオブジェクトが必要です。
(オブジェクト毎に違う値を取り得ます)
従って、オブジェクトの存在を前提としない
static関数からはアクセスできないのです。

>(2)(1)に関係しそうですが、Main.exeがマルチスレッドの場合に、
>   Main threadとsub threadから呼ぶときに、
>ライブラリのコンテキスト?インスタンス?は
>   同じなのでしょうか?それともスレッドごとに作られるのでしょうか?

先も述べたようにstatic関数にインスタンスは不要なのです。
これは、シングルスレッド、マルチスレッドとまったく違う次元の話です。
強いて言えば
マルチスレッドでもシングルスレッドでもインスタンスなしでアクセスできます。
staticメンバ関数が内部でstaticメンバ変数にアクセスしている場合
(よくあることです)
マルチスレッドの場合、排他をかけておかないと
正常動作しない可能性があります。

この回答への補足

ご指摘いただいたとおりstaticではないといけないですね。
説明不足のところいろいろお察しいただき感謝しております。

> static関数を呼び出すのにオブジェクトは必要ありません。
>(必要ないのでクラス名::の形式で呼べるのです)
> コンストラクタが呼ばれなくても動作します。

こちらですが、
static関数はstatic関数だけしか呼べないというのも合っていますでしょうか?
ちょっとstatic関数の理解ができていないかもしれません。
class内で定義したstatic関数(library::GetX();)とグローバル関数は
単に名前が違うものと思えばよいのでしょうか?

> 強いて言えば
> マルチスレッドでもシングルスレッドでもインスタンスなしでアクセ> スできます。

マルチスレッドではプロセス内の同じstatic関数を
どちらのスレッドからも実行できるということですね。

> staticメンバ関数が内部でstaticメンバ変数にアクセスしている場合
> (よくあることです)
> マルチスレッドの場合、排他をかけておかないと
> 正常動作しない可能性があります。

staticなものはそのプロセス単位?でただひとつしか存在しない、
存在することができないということだと思いますが、
異なるプロセス間ではどうなのでしょうか?
たとえば、プロセスA、Bがあり、Aのほうで定義(合っていますか?)した
static関数Aがあった場合、
プロセスBからstatic関数Aは呼べるのでしょうか?
もしくは、プロセスBで定義したstatic関数Bをstatic関数A内で
呼ぶことはできるのでしょうか?
よろしくおねがいします。

補足日時:2009/05/20 22:25
    • good
    • 0

> このとき、Main.exe内では、libraryをnewすることもなく、


> library::GetX();と呼べるわけですが、

staticじゃなきゃ呼べませんよ?

この回答への補足

ご指摘ありがとうございます。
staticでないと呼べないですね。

補足日時:2009/05/20 22:34
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QUNIX上のプログラムで使うライブラリの中身を知る方法

過去にUNIX上で動作するプログラムを作成していて、その中で多数の.aや.so(標準では無く、オリジナルのもの。)を使っているのですが、.aや.so内にどのような関数があるのか、もしくはそのライブラリに関係するソース名は何か知る手段ってありませんか?
かなり前のものなので、関数仕様書もmakefileも無いため、何をライブラリとしているのか分からず困っています。
駄目もとで、バイナリエディタで中身を確認してみたのですが、何処の情報がそれを示しているかいまいち分かりませんでした。

Aベストアンサー

No.2 の方がご回答されているように、nm コマンドを使えばシンボルの一覧を表示できます。

(ex.1)
$ nm /usr/local/lib/libssl.so
U ASN1_INTEGER_get
U ASN1_INTEGER_set
U ASN1_check_infinite_end
U ASN1_dup
U ASN1_get_object
U ASN1_object_size
U ASN1_put_object
U BIO_callback_ctrl
U BIO_copy_next_retry
U BIO_ctrl
U BIO_f_buffer
00027db0 T BIO_f_ssl

ただし、U となっているものはライブラリ内で未定義のシンボル (変数や関数) であり、他のライブラリによって解決されなければならないものだったと思います。

また、ライブラリが strip コマンドによって strip されてしまっている場合はシンボルテーブルが削除されてしまうため確認できません。

(ex.2)
$ nm /usr/lib/libstdc++.so.5
nm: /usr/lib/libstdc++.so.5: シンボルがありません

No.2 の方がご回答されているように、nm コマンドを使えばシンボルの一覧を表示できます。

(ex.1)
$ nm /usr/local/lib/libssl.so
U ASN1_INTEGER_get
U ASN1_INTEGER_set
U ASN1_check_infinite_end
U ASN1_dup
U ASN1_get_object
U ASN1_object_size
U ASN1_put_object
U BIO_callback_ctrl
U BIO_copy_next_retry
U BIO_ctrl
U BIO_f_buffer
00027db0 T BIO_f_ssl

ただし、U となって...続きを読む

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

C言語を用いてライブラリを作成しています。
ライブラリは機能ごとにファイルを分けています。
今、ライブラリの中でのみ使用するグローバル変数やグローバル関数が必要になりました。
このグローバル変数や関数は複数ファイルで参照するため、static宣言はできません。

しかし、このグローバル変数や関数は公開する必要はありません(ライブラリの中でのみ使用します)。


このようなことをC言語で実現するためにはどうしたらよいのでしょうか?

開発環境は
Windows7
VisualC++2010
です。

VisualC++2010を使うなら C++で書けばいいのではないかといわれそうですが、
C言語でプログラミングしたいのです。

以下のようなサイトがあったのですが、これを使うしかないでしょうか?
http://0xcc.net/blog/archives/000108.html

Aベストアンサー

スレッドセーフを意識する場合、ライブラリ内でグローバル変数を持つ事は許されません。

「一連の呼び出しの中で、グローバルなスコープが必要」なのであれば、fopen関数でやっているように「開始関数で一意のハンドラを返し、一意のハンドラを指定して一連の呼び出しを行ってもらい、終了処理で一意のハンドラを開放する」と言うような書き方をしないといけません。

fopenが「グローバル変数で、次に使える、空いているハンドラの番号を持っている」と言う実装があったとします。

もし、メインのスレッドでfopenが3番のハンドラを返そうと準備している真っ最中(fopenから、まだ帰って来てない状態)に、サブのスレッドがfopenを呼び出して3番のハンドラを受け取ったら、どうなると思いますか?

メインのスレッドも、サブのスレッドも、どっちも「3番のハンドラ」を受け取ります。

メインとサブで異なるファイルをオープンしているのに、ライブラリがグローバル変数で「次の空きは3番」なんて情報を持っていた所為で、両方とも「3番」を受け取ってしまったのです。

もちろん、実際のfopenは「マルチスレッドであっても一意」になっているヒープ領域を用いて「スレッドが切り替わっても大丈夫」な作り(つまり、スレッドセーフ)になっているので、こういう事は起きません。

ライブラリ内にグローバル変数を作ると「マルチスレッド禁止」になっちゃうので、スレッドセーフにするなら、グローバル変数は作ってはいけません。ライブラリ内の変数は、必ず「外にスコープを持たないstatic変数」にしないといけません。

スレッドセーフを意識する場合、ライブラリ内でグローバル変数を持つ事は許されません。

「一連の呼び出しの中で、グローバルなスコープが必要」なのであれば、fopen関数でやっているように「開始関数で一意のハンドラを返し、一意のハンドラを指定して一連の呼び出しを行ってもらい、終了処理で一意のハンドラを開放する」と言うような書き方をしないといけません。

fopenが「グローバル変数で、次に使える、空いているハンドラの番号を持っている」と言う実装があったとします。

もし、メインのスレッドでfop...続きを読む

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。


人気Q&Aランキング

おすすめ情報