ページ 11

違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 18:13
by ネス
皆さん、こんばんは。
早速ですが、質問です。

今、メインとなるソースがあまりにもごちゃごちゃしてきたので、ソースの分割およびヘッダーファイルの作成というのをやっています。確かに、これだと再利用もできて便利だなあという思いもしています。ただ、次のような問題が生じた場合、どうすればよいのでしょうか。


例えば、ストーリーの出力を扱う関数のヘッダーA.hと、プロセスエラー処理を扱う関数のヘッダーB.hがあったとします。
この場合、A.hで定義されているストーリ表示関数の中でも、プロセスエラー処理が置かれるとします。
しかし、A.hで、プロセスエラー処理を扱う関数を再び用意すると二重定義みたいなことになりますし、だからといって、A.h内で、例えば、#include "B.h"という記述を書いてもエラーになります。

どうすれば、違うヘッダー同士で、関数の呼び出しができるのでしょうか。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 18:18
by softya
問題のある具体例を書いてもらえますか?
勘違いされている可能性が高そうです。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 18:18
by シエル
>この場合、A.hで定義されているストーリ表示関数の中でも、プロセスエラー処理が置かれるとします。

この考えがおかしい。
最近のネスさんの質問を見ていると、ゲームプログラミングの館をしっかりやって、
基礎をもう一度勉強しなおしたほうがいいと思いますよ。 画像

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 18:39
by ネス
お二人、レスありがとうございます。
ご指摘のとおり、確かに基礎なきまま突っ走っている感、また質問内に雑談じみた発言もまじり、振り返るとここ連日、精細さを欠いた質問になっておりました。この点については、謹んでお詫び申し上げます。

>この場合、A.hで定義されているストーリ表示関数の中でも、プロセスエラー処理が置かれるとします。
>この考えがおかしい。

「関数1つにつき1つの処理」というルールを守っていないという点では、まったくそのとおりだなあと感じています。それで、具体例なのですが、こんな感じの話なんです。

//B.h
void PM ( void ) ;
void PM ( void )
{//PM開始
if ( ProcessMessage ( ) == -1 )
{//if開始
DxLib_End ( ) ;

}//if終了
}//PM終了

これで、PM ( )と書けば、上記の処理を出力できるようになりました。続いて、順序逆になりますが、ストーリー表示関数の方を。

//A.h
void Story2 ( void ) ;
void Story2 ( void )
{
DrawString ( ); //内容省略
  PM ( ) ;
DrawString ( ); //以下、同じ命令が続く。
PM ( ) ;

return ;
}

具体的には、上記のようなソースになっています。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 18:48
by ネス
さらに補足しますと、Story2 ( ) ;という関数では、紙芝居のような感覚で、絵とそれに応じた文章を最初から最後まで1つの関数内に収めてしまっています。
例えば、これで、Story2が第二話だとして、数話進んでから、伏線の回収のために、第XYZ話で第二話の内容を一気に引っ張り出してきたい場面などあれば、便利かなという、確かに安易な発想なのかもしれません。

そして、Story2の関数がおそらく常識はずれに、ひじょうに長いものになっているぶん、PM();のような関数もあればいいなということになり、そうなると定義してあるB.hから呼び出せるんじゃないか、みたいに考えていたのですが、やっぱり行儀というか基礎では、全然なっていなかったようで、この点につきましては心よりお詫びします。

手元に二種類、テキストがあるのですが、どちらにもヘッダーからヘッダーの呼び出しみたいなことは書いておらず、お二人のレスからして、自分がかなりトンチンカンなことをやっていたようで、書いていないのも当然かとは思いつつあります。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 18:58
by softya
とりあえずヘッダにプログラムの実行部分を書くのはマズイです。
void PM ( void ) ;
だけならOKです。
もし、この様なヘッダの書き方お紹介しているサイトを参考にしたのでしたらそのサイトも教えてください。

ファイル分割の参考サイトです。
http://www.geocities.jp/ky_webid/c/032.html
http://www.plustarnet.com/aspil/Programming/c22.htm
http://homepage3.nifty.com/mmgames/c_guide/20-02.html

今後のことを考えるなら苦Cなどで1から学習をお勧めします。
http://9cguide.appspot.com/

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 19:00
by シエル
何かあまり言ってることが良く分かりません^^;

softyaさんがおっしゃっているサイトで1から学習することをお勧めいたします。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 19:04
by palladium
分割ファイル
分割コンパイル
インクルードガード

などで検索されるとよいと思います。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 19:28
by h2so5
なんだかさらに話がこんがらがっている感じがしますが...

シエルさんのおっしゃっている
「この場合、A.hで定義されているストーリ表示関数の中でも、プロセスエラー処理が置かれるとします。」
がおかしい考えだ、
というのは文法の話ではなくゲームプログラミングの話ではないのですか?

普通に考えて ProcessMessage() の使い方が間違っている気がします。

追記:

あと質問があるのですが、ネスさんのおっしゃている
>Story2の関数がおそらく常識はずれに、ひじょうに長いものになっているぶん

の「長い」とは次のうちどのような意味でしょうか。

1.Cのソースが長い
2.ProcessMessage()を途中で呼び出さなければならないほど長くプログラムが停止する
3.Story2のシナリオが長くクリアするのに時間がかかる 画像

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 20:09
by シエル
h2so5さん。そうです。フォローありがとうございます><
ProcessMessage()の使われ方のことを言っています。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 20:23
by Dixq (管理人)
携帯なのであまり確認出来ていませんが、
普通ヘッダに実体はかかないですね。
ただ、コンストラクタやデストラクタなど簡単な物はヘッダに書いてしまう場合もあります。

2重インクルード防止の処置をほどこす方法は昨日DecentLoveさんのトピックで紹介しましたのでご覧ください。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 20:32
by palladium
ヘッダーファイルに関数の定義を記述する場合には長所・短所があるようです

参考リンク
http://ja.wikipedia.org/wiki/%E3%82%A4% ... 5%E9%96%8B

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 20:46
by ネス
皆さん、レスありがとうございます。
シエルさん、文法ではなく、プロセスメッセージについてでしたか。理解が及びませんで、重ね重ね、申し訳ありません。

>この様なヘッダの書き方お紹介しているサイトを参考にしたのでしたらそのサイトも教えてください。
いえいえ、すべて私の思い違いが原因です。そのようなテキストやサイトはございません。
結局、「プロトタイプ宣言のみならず、関数定義までヘッダーに書いていい」という、大きな思い違いをしていたようです。

関数については、他のソースに分割はしても、ヘッダに書くというようなことはされていませんでした。それを私がすっかりヘッダに関数定義までしていいと、とんだ早とちりをしていた次第です。


>普通に考えて ProcessMessage() の使い方が間違っている気がします。
h2so5さん、私の言葉足らずでした。「長い」というのは、Story2関数内で、とりあえず1つの話が成立しているという意味での長いです。今回作っているのは、一話につき30分から一時間ぐらいで読み進めるだけのプログラムです。第一話を作って見て、今は第二話を作っている最中でした。


それで、本題のProcessMessageですが、私の理解では、他のプログラムおよびユーザーからの予定外のイベントへの対処関数といった理解です。物語を読み進める途中で、ユーザーが他のプログラムに切り替えたり、あるいは終了させたりといったことを行った場合、ウィンドウは閉じられたけど、プログラムだけは動いていて、まだ音楽だけ鳴っているとか、そんな状況を防ぐのに使っています。また、そういうものだというのが今のところの理解です。それだけに、文章表示のたび(次の場面へとページをめくるたび)に、呼び出すような使い方をしていました。


結構な頻度で呼び出すべきものなのかなと思っていますが、そうではないのでしょうか。







ヘッダーファイルが関数を定義をするファイルだ

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 20:56
by ネス
あ、直前の私の記事に文章ミスが。
最後の行は、単なる消し忘れですorz
読み飛ばしてください。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 21:04
by h2so5
>結構な頻度で呼び出すべきものなのかなと思っていますが、そうではないのでしょうか。

確かにProcessMessage()は結構な頻度で呼びますが、
ユーザーの入力などに関係なく一定時間ごとに呼ぶのが普通です。
(このサイトの講座を見ればわかると思いますが)

ネスさんの書き方だとユーザーがページを進めない限りProcessMessage()が呼ばれません。

ユーザーの入力でページを進めるのであれば、
キーやマウスの状態を一定時間ごとにチェックしているはずなのでそこでProcessMessage()を呼ぶべきです。
ついでに言えば画面への描画処理もです。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 21:10
by softya
ヘッダにC99のインライン展開やC++のクラスを書くときなど狙って書く場合なら良いですが、良く分からないのに関数の実体を書くのは避けたほうが無難と言うかエラーになるだけです。

ProcessMessage()は実のところ一秒間に数十回ほど呼び出してやればOKで、今の書き方で大きな問題はないと思いますが普通のプログラムの書き方ではないので効率はかなり悪いです。
それに、このままだとstory1と2を一本に結合するときに大変苦労しそうなんですね。シナリオの追加とかも大変なんじゃないかと思うんですがネスさんこのプログラム構造のまま進めるおつもりでしょうか?

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 21:14
by softya
>ネスさんの書き方だとユーザーがページを進めない限りProcessMessage()が呼ばれません。

あぁ、それはDXライブラリが親切なのでWaitKey()やWaitTimer()を呼ぶ限り内部でProcessMessage()が呼び出されます。
http://homepage2.nifty.com/natupaji/DxL ... .html#R6N1
http://homepage2.nifty.com/natupaji/DxL ... .html#R6N3

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 21:16
by シエル
http://dixq.net/g/43.html

↑このページのココ!って書いてる中だけで処理するようにしてください。
他の場所でProcessMessageは呼び出すような構造にするのはよしたほうが良いかと。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 21:53
by palladium
>ヘッダにC99のインライン展開やC++のクラスを書くときなど狙って書く場合なら良いですが、良く分からないのに関数の実体を書くのは避けたほうが無難と言うかエラーになるだけです。

その方が御自身で学ばない限りいつまでたっても理解できません。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 22:12
by ネス
皆さんレスありがとうございます。
では、while(ProcessMessage()==0 )を最初に書くことで、絶えず監視されているという理解でよいのでしょうか。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 22:26
by h2so5
while(ProcessMessage()==0)ではなく

while(ProcessMessage()==0 ){

}

で一つのかたまりです。
単にループ内の処理が実行される前に毎回ProcessMessage()が呼ばれるだけです。

どうも根本的に理解されていないことが多いような気がします。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 22:30
by シエル
ゲームプログラミングの館を最初から順番にやって理解していけば、
こんなところでは悩まないはずです。
何度も言いますが基本は大事ですよ。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 22:35
by ネス
h2so5さん、レスありがとうございます。また、ご指摘のとおりです。
ただ、自分的にはどうも、while文が分かったとしても、ProcessMessage()がゼロの間はカッコ内の処理を繰り返すという解釈で、実際、どのタイミングでゼロか否かが判定されているのか、分かりませんでした。そこで、ウェイトキーのたびに、ProcessMessage()処理を置いていたという次第です。


>結合するときに大変苦労しそう

softyaさん、そうですね、それはさすがに自分も感じております。それで先日、教えてくださったリンク先でノベルゲーム基礎などやろうとしているのですが、乗りかかった船といいますか、作りかけのぶんだけ強引にでも最後までやりきってしまおうかというところで、こうした御迷惑をおかけすることになりました。


せっかくC言語の知識が不十分でも取り組める形で良いコンテンツや掲示板など用意されているのに、その想定のさらに下を行く形で質問をしてしまい、その点では、皆さんに大変、申し訳ないと思っております。


とりあえず、今のぶんだけでも最後まで作って、その後しばらくはC言語をイチから取り組んでみたいと思っています。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月27日(金) 22:36
by ネス
とりあえず回答も出揃ったので、これで解決としたいと思います。

Re:違うヘッダーファイル同士の関数の呼び出し

Posted: 2010年8月28日(土) 04:06
by ISLe
ゲームプログラミングは、
while(ProcessMessage()==0){

     //ココ!! 
 
     ScreenFlip();
  }
のようにメインループを作りますね。

このメインループはここにひとつだけあって、1フレームごとに一回ループするように作るのが基本です。
『ココ!! 』にどんなに深い関数呼び出しがあっても1フレーム分の処理をして必ず戻ってきてください。

DXライブラリ(というかウインドウズプログラム)は自由度が高いのでコピペしてループをいくつも並べたり入れ子にしたりできますが、そういうプログラムは(ゲームプログラムとしては)とても保守しにくいプログラムになります。

ゲームプログラミングの館には「ゲームを作ったりサンプルを考えたりする時は毎回このコードをコピペして下さい。」と紹介されているのですが、初めてゲームをつくる人のほとんどがウエイトの必要なところにどんどん貼り付けて良いと解釈するみたいです。