ヘッダファイルについてうまくいかない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
cupa
記事: 117
登録日時: 2年前

ヘッダファイルについてうまくいかない

#1

投稿記事 by cupa » 2年前

一つのファイルにまとめようとすると、目的のものがどこにあるかわからなくなってしまので、
ファイルを分けようと思ったのですが、うまくいきません

ファイル構成:
  フォルダの中に、ソースが入っていてすべて同じディレクトリです。
  main.cpp, window.cpp, window.hがあります。

main.cpp

コード:

#include "../DxLib/DxLib.h"		// DxLib.hをインクルード
#include "window.h"

#define SCREEN_WIDTH    (1366)		// スクリーンの横幅
#define SCREEN_HEIGHT   (768)		// スクリーンの縦幅

const int menu_num = 3;		// メニュー項目の数

int nowSelect;		// 現在選択されている項目
int textWidth;		// 文字の横幅を格納する変数
int mouseX, mouseY;		// マウスのX座標、Y座標

void is_full_screen();		// フルスクリーンで表示するか?の関数
void mouse_hover_detection();		// マウスホバーを検知する関数

typedef struct {
    int tibg;		// タイトル画面の背景
    int stdreimu;		// 立ち絵の霊夢
    int spark;		// 火の粉
}IMG;		// IMGという型名をつける

IMG img {		// IMG型のimgを生成
    LoadGraph("imgs/タイトル画面の背景.jpg"),			// 
    LoadGraph("imgs/主人公/霊夢/reimu_a/霊夢_通常.png"),// ロード
    LoadGraph("imgs/火の粉.png")						//
};

typedef struct {		// 色を格納する型
    unsigned int Write;
    unsigned int Black;
    unsigned int Green;
    unsigned int Yellow;
    unsigned int Red;
}COLOR;

COLOR color {			// 色を設定
    GetColor(255, 255, 255),
    GetColor(  0,   0,   0),
    GetColor(  0,   0, 128),
    GetColor(255, 255,   0),
    GetColor(255,   0,   0)
};

typedef struct {		// メニューの型
    int x, y;		// X座標とY座標(左上)
    unsigned int color;		// フォントの色
    char name[32];		// 名前
}MENU;

MENU menu[menu_num] {		// メニュー項目をmenu_num分生成(配列)
    {1000,       400,       color.Write, "Game Start"},
    {1000 - 50,  400 + 80,  color.Write, "Option"},
    {1000 - 100, 400 + 160, color.Write, "Game Finish"}
};

enum {
    TITLE,		// タイトル画面
    GAME,		// ゲーム画面
    RESULT		// リザルト画面
}scene = TITLE;		// 初期値はタイトル画面

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    is_full_screen();
    SetDrawScreen(DX_SCREEN_BACK);		// 描画先を裏画面にセット
    SetMouseDispFlag(TRUE);		// マウスを表示する
    SetMainWindowText("東方静天地");		// タイトルを設定
    if (DxLib_Init() == -1) return -1;		// DxLibの初期化(エラーが発生したら終了)
    ChangeFontType(DX_FONTTYPE_ANTIALIASING_EDGE_8X8);		// フォントタイプをアンチエイリアス・エッジ付きに変更(8x8)
    SetFontSize(50);		// フォントサイズを50に変更

    while(ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)		// エラー無・ESCが押されていないならループする
    {
        ClearDrawScreen();	// 画面をクリア

        GetMousePoint(&mouseX, &mouseY);		// マウスの位置を取得(mouseX, mouseYに代入)

        mouse_hover_detection();
    	
    	test();		// test() の呼び出し

        ScreenFlip();		// 裏画面に表示されていたものを表画面に描画
    }

    DxLib_End();	// DxLibを終了

    return 0;		// プログラムの終了
}

void is_full_screen() {
    int result = MessageBox(
        NULL,
        "フルスクリーンで表示しますか?",	// 説明
        "スクリーンの設定",		// 題名
        MB_YESNO		// YES or NO で送信
    );

    switch(result) {
        case IDYES:		// YES なら
            SetGraphMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32);	// 画面いっぱいに設定
            ChangeWindowMode(FALSE);		// ウィンドウモードにしない
            break;
        case IDNO:		// NO なら
            SetGraphMode(SCREEN_WIDTH, SCREEN_HEIGHT - 20, 32);		// 少し小さく
            SetWindowInitPosition(-8, 0);		// 細かい位置調整
            ChangeWindowMode(TRUE);		// ウィンドウモードにする
            break;
    }
}

void mouse_hover_detection() {
    for (int i = 0; i < menu_num; i++) {
        DrawFormatString(menu[i].x, menu[i].y, menu[i].color, menu[i].name);	// メニュー項目を表示
        textWidth = GetDrawFormatStringWidth(menu[nowSelect].name);   	// 選択されているテキストの幅を取得
        if (menu[i].x <= mouseX && menu[i].x + textWidth >= mouseX &&
            menu[i].y <= mouseY && menu[i].y + 50 >= mouseY) {
                nowSelect = i;		// 条件を満たしていればその数をnowSelectに代入
                menu[nowSelect].color = color.Red;	// 色変更
            } else {		// それ以外は
                menu[i].color = color.Write;	// 白
            }
        }
}
window.cpp

コード:

#include "../DxLib/DxLib.h"

void test() {
	DrawString(0, 0, GetColor(255, 255, 255), "分離できています");	
}
window.h

コード:

#ifdef WINDOW_H
define WINDOW_H

void test();

#endif WINDOW_H
main.cppのはじめにwindow.hを読み込んで、Whileの中でtest()を呼んでいます。
お願いします

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#2

投稿記事 by cupa » 2年前

コンパイラはCLです。
Visual Studioで編集はせず、コンパイルだけVSでやってます。
#pragma once でやったらよくわからないエラー?が出たので従来の方でやったらそのエラーはなくなりました

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#3

投稿記事 by あたっしゅ » 2年前

東上☆海美☆「
window.h

コード:

#ifdef WINDOW_H
define WINDOW_H
「もし WINDOW_H が定義されていたら」
じゃなくて

コード:

#ifndef WINDOW_H
#define WINDOW_H
「もし WINDOW_H が定義されていなかったら」でみみ。
あと、#define と # が頭につくみみ。
window.cpp で #include "window.h" がないのは、window.h を作った以上は、おかしいみみ。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#4

投稿記事 by cupa » 2年前

回答ありがとうございます。
些細なミスで失敬失敬、と思って#をつけてもう一度やってみたのですが、
まだ、testが定義されていません、と言われます・・・

box
記事: 2002
登録日時: 13年前

Re: ヘッダファイルについてうまくいかない

#5

投稿記事 by box » 2年前

window.cpp
の2行目に
#include "window.h"
と書いたらどうなりますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#6

投稿記事 by みけCAT » 2年前

cupa さんが書きました:
2年前
#をつけてもう一度やってみたのですが、
ifdef を ifndef にする修正もしましたか?
cupa さんが書きました:
2年前
まだ、testが定義されていません、と言われます・・・
これはコンパイル時ですか?リンク時ですか?
box さんが書きました:
2年前
window.cpp
の2行目に
#include "window.h"
と書いたらどうなりますか?
結果は変わらないと予想できます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#7

投稿記事 by あたっしゅ » 2年前

東上☆海美☆「
いままで、ソースを眺めるだけで、実際にビルドしていなかったので、
ビルドしてみた。

window.h と window.cpp の名前が縁起悪そうなので、mywindow.h と mywindow.cpp に変えた。

mywindow.h

コード:

#ifndef MYWINDOW_H
#define MYWINDOW_H

void test();
//extern void test();

#endif MYWINDOW_H
実際にやってみたら、extern 抜きでもビルドできるみみ。

あと、mywindow.cpp

コード:

#include "DxLib.h"
#include "mywindow.h"


void test() {
	////DrawString(0, 0, GetColor(255, 255, 255), "分離できています");
	DrawString(0, 0, "分離できています", GetColor(255, 255, 255 ) );
}


// end.
DxLib の関数 DrawString の引数の順番が逆みみ。
#include "DxLib.h" に関しては、自分の dxlib.h の位置に合わせて変えてあるみみ。

とりあえず、フルスクリーンでは、マウスカーソルが消えてしまっていたが、
ウインドウ・モードで、マウス・オーバーすると、文字の色が変わった。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#8

投稿記事 by cupa » 2年前

まず、boxさんの案のwindow.cppにもwindow.hをインクルードしてみましたがみけCATさんの予想通り結果は変わりませんでした。
エラーは次の通りです 

コード:

main.cpp(84): error C3861: 'test': 識別子が見つかりませんでした
次に、みけCATさんの案の一つ目をやってみたら次のエラー?が出ました

コード:

main.obj : error LNK2019: 未解決の外部シンボル "void __cdecl test(void)" (?test@@YAXXZ) が関数 _WinMain@16 で参 照されました
  定義済みの一致する可能性があるシンボルに関するヒント:
    "public: bool __thiscall __crt_stdio_input::scanset_buffer<unsigned char>::test(unsigned char)const " (?test@?$scanset_buffer@E@__crt_stdio_input@@QBE_NE@Z)
    "public: bool __thiscall __crt_stdio_input::scanset_buffer<wchar_t>::test(wchar_t)const " (?test@?$scanset_buffer@_W@__crt_stdio_input@@QBE_N_W@Z)
main.exe : fatal error LNK1120: 1 件の未解決の外部参照
エラーはC3861といわれているのでコンパイルエラーだと思われます(linkのエラーなら「link」と書かれていた気がするので)
あたっしゅさん、DrawStringのご教授ありがとうございます。
フルスクリーンにするとマウスが消えてしまう問題は、DxLibの初期化の後にその関数を呼んだら直りました。
「window」が縁起が悪いのはなぜでしょうか?

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#9

投稿記事 by cupa » 2年前

二個目のエラーの方はLNK1120と書かれているのでリンクエラーですかね

アバター
usao
記事: 1889
登録日時: 11年前

Re: ヘッダファイルについてうまくいかない

#10

投稿記事 by usao » 2年前

> Visual Studioで編集はせず、コンパイルだけVSでやってます。

というのが具体的にどういう状況なのかよくわからんけども,

main.cpp と window.cpp という2つの翻訳単位をコンパイルして

その結果できた2つのオブジェクトファイル(main.obj, window.obj かな)をリンクする必要があると見えるが,

・window.cpp をコンパイルする
・window.obj をリンク対象にする

のあたりは大丈夫?
Visual Strudio を素直に使ってれば特段何の苦労も発生しない(勝手に面倒見てもらえる)ところだが.

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#11

投稿記事 by cupa » 2年前

usaoさん、たぶんそれをわすれていました。
そのため、どっちもコンパイルしようとしたのですが、次のエラーが出ます。

コード:

DxDataType.h(14): fatal error C1083: include ファイルを開けません。'stdio.h':No such file or directory
これはどういうことでしょうか?
stdio.hを開けないということでしょうか?
(DxLibのPathは通してあるので大丈夫だと思います)

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#12

投稿記事 by cupa » 2年前

CMDを一度再起動したらそのエラーはなくなりました。
そして、cl /c window.cpp
    cl /c main.cpp
main.cppの方でtestが見つからない、と言われます。
そのあとに、

コード:

link window.cpp /OUT:main.exe
とやったのですが、main.cppのコンパイルがうまくいってないからなのか、

コード:

window.cpp : fatal error LNK1107: ファイルが無効であるか、または壊れています: 0x116 を読み取れません。
というエラーが出ます・・・

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#13

投稿記事 by cupa » 2年前

やり方があってるいるかは定かではありません・・・

アバター
usao
記事: 1889
登録日時: 11年前

Re: ヘッダファイルについてうまくいかない

#14

投稿記事 by usao » 2年前

> link window.cpp /OUT:main.exe

なんでリンカに .cpp を食わせようとしてるの?

> 2つのオブジェクトファイル(main.obj, window.obj かな)をリンクする必要がある

っていう話ならば,
【少なくともリンカにはこの2つの .obj のファイル名を指定する必要がありそうだなぁ】とは考えないの?
オフトピック
個人的にはわざわざ cl とかを直にコマンドラインから叩こうとする意味がわからんが…

あえてそんなことに挑むのならば,そういう話に手を出すための最低限の物事の勉強(というか調べもの)は先に済ますべきちゃうん?
「何をどうすれば→できるはず」っていう筋道すらない状態でてきとーにコマンド叩いてるとしたら,その行動理念が理解できん.

アバター
usao
記事: 1889
登録日時: 11年前

Re: ヘッダファイルについてうまくいかない

#15

投稿記事 by usao » 2年前

とりあえず「やり方」を
「cl 分割コンパイル」だとか適当にそれっぽい言葉でググってみたら?

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#16

投稿記事 by cupa » 2年前

すみません、普通に

コード:

cl main.cpp window.cpp /EHsc -I"DxLibのパス" /link /LIBPATH:"DxLibのパス"
「DxLibのパス」は実際のパスが入ります。
とやったらwindow.hも読み込めていて、”分離できています”が表示されました。
いつもやるのは少し長いので、makefileを作ってみようと思います。

VSを使わないのは、自分のPCのスペックが低く、重すぎるからです・・・

皆さんありがとうございました。

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#17

投稿記事 by あたっしゅ » 2年前

東上☆海美☆「
viewtopic.php?f=3&t=21347
Visual Stdio 2019 community のダウンロードできる場所 - ミクプラ(ja)

にも書いたけど、

https://visualstudio.microsoft.com/ja/v ... downloads/
最新の Visual Studio はお試しになりましたか?...以前のバージョンをお使いになりたいですか? - Microsoft(ja)

で、動きそうな Visual Studio Express 版とか Community 版を試してみたらいかかみみ。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#18

投稿記事 by cupa » 2年前

すみません、終わった感じを出しましたけど、わかったことが一つありまして・・・

コード:

cl main.cpp window.cpp ~~~
で通ったのは一回VSでプロジェクトを作成したものをコンパイルしたからだと思います。
その後、VSのファイル・フォルダを削除してやったらダメでした。

usaoさんに言われたとおりググってみたのですが、
どのサイトもまずは.objを作ってそれをlinkを使って.exeを作る?みたいな感じした。
はじめに

コード:

cl /c main.cpp
をやるのですが、その際にtestがないと言われて
.objが作れません(window.cppの方は普通に作れます)

本当だったら、

コード:

cl /c main.cpp
(window.cppも)
をやってから、

コード:

link main.obj window.obj /OUT:main.exe
とやりたのですが・・・main.objを作るにはどうしたら良いでしょうか?

また、Visual Studioはバージョンが古いほうが軽いのでしょうか、それとも逆でしょうか?

アバター
usao
記事: 1889
登録日時: 11年前

Re: ヘッダファイルについてうまくいかない

#19

投稿記事 by usao » 2年前

DXライブラリを持ってないし導入するのも嫌なので,すごい単純な下記のコードでテストしてみたが,

「開発者コマンド プロンプト for VS 2017」起動して,ソースがある場所まで行って

cl /c main.cpp
cl /c window.cpp
link main.obj window.obj /OUT:test.exe

でふつーにいける.
※コンパイル時に

> C4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効にはなりません。/EHsc を指定してください。

っていう warning は出たけども.

---

main.cpp :

コード:

#include <iostream>
int Test();
int main()
{
	std::cout << Test() << std::endl;
	return 0;
}
window.cpp :

コード:

int Test(){	return 77;	}

アバター
usao
記事: 1889
登録日時: 11年前

Re: ヘッダファイルについてうまくいかない

#20

投稿記事 by usao » 2年前

…ということで,
とりあえずこのくらいの簡素なコードならいけるんか? ってのを試してみてはどうか.

これなら問題無くexeまで作れるということであれば,
コンパイルのために打ってるコマンドの側ではなくて,あなたの現状のソースコードの記述のどこかに問題がある とかかもしれないし.

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#21

投稿記事 by cupa » 2年前

自分もusaoさんのとおりにやったらうまくいったのですが、
ヘッダファイルを作って宣言をヘッダファイルでやると、うまくいきません

window.h

コード:

#ifdef WINDOW_H
#define WINDOW_H

int test();    //  つまりはこういうことです

#endif WINDOW_H

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#22

投稿記事 by cupa » 2年前

extern?(よくわかってないです)を付けなければならないのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#23

投稿記事 by みけCAT » 2年前

ヘッダファイルに宣言を書いてうまくいきました。

main.cpp

コード:

#include <iostream>
#include "test.h"

int main(void) {
	std::cout << "main 1\n";
	test();
	std::cout << "main 2\n";
	return 0;
}
test.cpp

コード:

#include <iostream>

void test(void) {
	std::cout << "test\n";
}
test.h

コード:

#ifndef TEST_H
#define TEST_H

void test(void);

#endif
header_test.png
header_test.png (51.26 KiB) 閲覧数: 11970 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#24

投稿記事 by みけCAT » 2年前

cupa さんが書きました:
2年前
window.h

コード:

#ifdef WINDOW_H
#define WINDOW_H

int test();    //  つまりはこういうことです

#endif WINDOW_H
また ifndef のかわりに ifdef を使っている、ということですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

cupa
記事: 117
登録日時: 2年前

Re: ヘッダファイルについてうまくいかない

#25

投稿記事 by cupa » 2年前

すみません、ifndefにしたら直りました。
どこかのサイトにifdefと書いてあったのか間違えて書いたのかわかりませんが・・・
ありがとうございます。

コンパイル時にwarningがたくさん出てくるのですが、これを消す方法はありますでしょうか?
見たところ、C4530です、C++だからでしょうか

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ヘッダファイルについてうまくいかない

#26

投稿記事 by みけCAT » 2年前

「C4530」でググった最初の2個
コンパイラの警告 (レベル 1) C4530 | Microsoft Docs
アンワインド セマンティクス って何? | の回想録

メッセージの通り、オプション /EHsc を追加すればいいのではないのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

“C言語何でも質問掲示板” へ戻る