error LNK1120: 1 件の未解決の外部参照のエラーについて...

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

error LNK1120: 1 件の未解決の外部参照のエラーについて...

#1

投稿記事 by じゃじゃかぶ » 11年前

visualC++でサンプルコードを参考に簡易スクリプトエンジンを組んでいたのですがどうしても自力で解決できないエラーが出ました。
「エラー 2 error LNK1120: 1 件の未解決の外部参照」
「エラー 1 error LNK2019: 未解決の外部シンボル "public: int __thiscall ScriptImport::decodeScript(char const *)" (?decodeScript@ScriptImport@@QAEHPBD@Z) が関数 _WinMain@16 で参照されました。」

です。
自分で調べられたのは多分decodeScript(char const* scriptMessage)関数の定義と引数の兼ね合いがうまくいってないとかで、実際メイン関数のところで書いているdecodeScriptが使われているコードをコメントアウトしてみたところ一応コンパイルは通りました。
しかしどういじればいいのかが分かりません。
実際の引数がポインタではないからかと思って、試しにdecordScript関数に別のconst char* a = "~";とかいう適当な変数を作って引数にしてみても同様のエラーがでます。
どこが問題なのでしょうか。。。
ちなみにDXライブラリは今は関係ありませんが後々使おうと思ってたので骨組みだけ入れてます。

[Main.cpp]

コード:

#include "DxLib.h"
#include "ScriptImport.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定

	//コンソール画面の呼び出し
	AllocConsole();
	FILE* fp;
	freopen_s(&fp, "CONOUT$", "w", stdout);
	freopen_s(&fp, "CONIN$", "r", stdin);
	int i;
	ScriptImport script;		
	script.loadScript("./script.txt", &script);
	for (i = 0; i < 5; i++){
		printf("%d : %s\n", i+1,script.script[i]);
	}	
	for (i = 0; script.decodeScript( script.script[i] ) != 0; i++){
		;
	}
	// while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){
	}
	FreeConsole();//コンソールの解放
	DxLib_End(); // DXライブラリ終了処理
	return 0;
}
[/size]

[ScriptImport.h]

コード:

#ifndef DEF_SCRIPTIMPORT_H
#define DEF_SCRIPTIMPORT_H
#define SCRIPT_MAX_LINE 1000
#define SCRIPT_MAX_LENGTH 60
class ScriptImport{
	int maxLineNumber;	//スクリプト行数
	int currentLine;	//現在実行している行数
	const char* filename;	//ファイル名
public:
	char script[SCRIPT_MAX_LINE][SCRIPT_MAX_LENGTH];
	int loadScript(const char* filename, ScriptImport* scriptInfo);
	void splitString(const char* src, char* dest[], const char* delim, int splitNum);
	void printElements(char* elem[]);
	int decodeScript(const char* scriptMessage);
};
#endif
[/size]

[ScriptImport.cpp]

コード:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ScriptImport.h"
int ScriptImport::loadScript(const char* filename, ScriptImport* scriptInfo)
{
	int pos;
	char c;
	FILE* fp;
	errno_t error;
	//スクリプト初期化(重要)
	memset(scriptInfo, 0, sizeof(script));
	//スクリプトファイルを開く
	if (error = fopen_s(&fp, filename, "r") != 0){
		//読み込みエラー
		printf("スクリプトを読み込めませんでした。\n", filename);
		return -1;
	}
	pos = 0;
	while (1){
		//一文字読み込み
		c = fgetc( fp );
		//ファイルの終わりかチェック
		if (feof(fp)){
			break;
		}
		//文章先頭の空白部分を読み飛ばす
		while ((c == ' ' || c == '\t') && pos == 0 && !feof(fp))
		{
			c = fgetc(fp);
		}
		if (pos >= SCRIPT_MAX_LENGTH - 1){
			//一行の文字数制限超過
			printf("error:文字数が多すぎます(%d行目)",scriptInfo->currentLine);
			return -1;
		}
		//改行文字が出てきたら次の行へ移動
		if (c == '\n'){
			//空行は読み飛ばす
			if (pos == 0){
				continue;
			}
			//\0を文字列の最後に付加
			scriptInfo->script[scriptInfo->currentLine][pos] = '\0';
			//次の行へ移動
			scriptInfo->currentLine++;
			//書き込み位置を0に戻す
			pos = 0;
		}
		else{
			//書き込み
			scriptInfo->script[scriptInfo->currentLine][pos] = c;
			//文字書き込み位置をずらす
			pos++;
		}
	}
	//最大行数
	scriptInfo->maxLineNumber = scriptInfo->currentLine;
	//読み込み中の行を0にする
	scriptInfo->currentLine = 0;
	//スクリプトファイル名を設定
	scriptInfo->filename = filename;
	return 0;
}
//文字列分割
//src:分割したい文字列//dest:分割された文字列//delim:区切り文字//splitNum:最大分割数
void ScriptImport::splitString(const char* src, char* dest[], const char* delim, int splitNum){
	int i;
	char* cp;
	char* copySrc;
	char* nexttoken;
	//元の文章分メモリを動的確保
	copySrc = (char*)malloc( sizeof(int) * SCRIPT_MAX_LENGTH + 1);
	//memset(copySrc,0,sizeof(copySrc));
	//元の文章をコピーする
	//strncpy(対象文字列,対象文字列のサイズ,ソース文字列,コピーする文字数または_TRUNCATE);
	strncpy_s(copySrc, SCRIPT_MAX_LENGTH, src, SCRIPT_MAX_LENGTH);
	cp = copySrc;	
		//strtokを使ってcopySrcをdelim区切りで分割する
	for (i = 0; i < splitNum; i++){
		//分割対象が無くなるまで分割
		if (  (dest[i] = strtok_s(cp, delim, &nexttoken)) == NULL  ){
			break;
		}
		//2回めにstrtokを呼び出す時はcpをNULLにしておく
		cp = NULL;
	}
	//分割された文字列の最後の要素はNULLとしておく
	dest[i] = NULL;
}
//デバッグ用、elemの要素を表示
void ScriptImport::printElements(char* elem[])
{
	int i;
	for (i = 0; elem[i] != NULL; i++){
		printf("%d : %s\n", i + 1, elem[i]);
	}
}
//スクリプト文解読//戻り値 1:成功 0:失敗
int ScriptImport::decodeScript(const char* scriptMessage)
{
	//分割されたスクリプト文
	char* message[100];
	//文字列分割時の区切り文字
	const char* delim = " ";
	//スクリプト分割
	ScriptImport::splitString(scriptMessage, message, delim, 100);
	//分割に失敗した場合
	if (message[0] == NULL){
		return 0;
	}
	//scriptの仕様
	//
	//@@message 文字列
	//--- 文字列をメッセージとして表示する
	//
	//@@drawgraph x y filename
	//--- filenameで指定した画像ファイルを(x,y)の位置に表示
	//message[0]が@@messageの時はメッセージ命令が来たと判断
	if ( strncmp(message[0], "@@message", SCRIPT_MAX_LENGTH) == 0){
		printf("メッセージ:%s\n", message[1]);
		return 1;
	}
	else if (strncmp(message[0], "@@drawgraph", SCRIPT_MAX_LENGTH) == 0){
		printf("画像 %s 表示 -- x座標 : %d, y座標 : %d\n", message[3], atoi(message[1]), atoi(message[2]));
		return 1;
	}
	printf("スクリプトエラー\n");
	return 0;
}
[/size]

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: error LNK1120: 1 件の未解決の外部参照のエラーについて...

#2

投稿記事 by h2so5 » 11年前

リビルドしてみるとエラーが出ないようになるかもしれません。

あと、本題とは違いますがC++の入門書などを一通り読むことをお勧めします。
コードを見るとC言語の知識だけで書いていて、C++の理解が不足しているのでいろいろと問題があります。

じゃじゃかぶ
記事: 11
登録日時: 11年前

Re: error LNK1120: 1 件の未解決の外部参照のエラーについて...

#3

投稿記事 by じゃじゃかぶ » 11年前

>>h2so5様
返信ありがとうございます。出先なので帰り次第試してみます。
それからこのサンプルコード、元はC言語で書かれていたもので、勉強がてらに自分のかじった程度の知識でC++に落とし込んでみたものなのです。やはりかなり甘かったようですね。。。自分の周りにコードレビューしてくれるような方がいないのでダメだしはとても勉強になります。もしよろしければ簡単にでも気になる点挙げて頂けないでしょうか。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: error LNK1120: 1 件の未解決の外部参照のエラーについて...

#4

投稿記事 by h2so5 » 11年前

コードレビュー以前に、一度ひと通りC++の機能を押さえてから書いたほうがいいと思います。
  • なるべくC++の標準ライブラリを使ってください。
  • 文字列にはstd::stringを使ったほうが便利です。
  • ScriptImport::loadScriptの第二引数は不要です。thisを使ってください。
  • インスタンスをmemsetで初期化するのは止めたほうがよいです。初期値を代入するのが自然だと思います。
  • Main.cppの14~19行目の処理はScriptImport内部で完結できるはずです。

じゃじゃかぶ
記事: 11
登録日時: 11年前

Re: error LNK1120: 1 件の未解決の外部参照のエラーについて...

#5

投稿記事 by じゃじゃかぶ » 11年前

>>h2so5様
返信ありがとうございます。これらを取っ掛かりに本腰入れて勉強してみます。
それとリビルトでもやはりうまくいきませんでした......。

閉鎖

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