「エラー 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;
}
[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
[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;
}