初めまして。いつもDXライブラリを使わせていただいております。
メモリ上に読み込んだDXアーカイブからテキストファイルを FileRead 系関数によって操作しようとする際、
アクセス違反のエラーが発生してしまう場合があります。
エラー発生の有無はテキストファイルの内容に依存する模様で、
テキストファイルの圧縮が原因とみられるようですが解消の手段がわかりません。
DXアーカイブはメモリに読み込んだ後 DxArchiveSetMemImage でフォルダ扱いにしています。
以下テストです。お手数ですが以下のファイルをご用意ください。
(一応リンク先に置いてはあります
https://drive.google.com/open?id=1kx145HpHjCjxVZmqvYur0Tw33H1o_RYV )
data16.dxa
- a.txt ("a"が16個連続するだけのテキストファイル)
data17.dxa
- a.txt ("a"が17個連続するだけのテキストファイル)
Flag.txt ("00"又は"01"又は"10"又は"11"と記述したテキストファイル)
DXアーカイブはそれぞれパスワード設定無しでアーカイバにかけただけのものとします。
検証のためメモリ上に読み込んだものを再度ファイルとして吐き出して、
メモリへの読み込みやサイズの取得自体が失敗しているわけではないことを確認しています。
Flag.txtの内容に依って以下の動作をします
[Flag.txt]
00 : data16を出力して使用します
01 : data16をメモリ上で使用します
10 : data17を出力して使用します
11 : data17をメモリ上で使用します // FileRead関数を呼び出した時点でアクセス違反が出ます
以下テストコードです
#include "DxLib.h"
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int nCmdShow){
SetUseDXArchiveFlag(TRUE);
ChangeWindowMode(TRUE);
if(DxLib_Init() == -1)
return -1;
FILE *fp;
bool useDXArcMem = true;
int numUseData = 16;
char buf[3];
//設定の読み込み
fopen_s(&fp, "Flag.txt", "r");
if(fp != NULL){
fgets(buf, sizeof(buf), fp);
numUseData = buf[0] == '0' ? 16 : 17;
useDXArcMem = buf[1] == '1' ? true : false;
fclose(fp);
}
fopen_s(&fp, "output.txt", "w");
if(fp != NULL){
fprintf_s(fp, "%s : data%dを%s使用します\n",
buf,
numUseData,
useDXArcMem ? "メモリ上で" : "出力して");
fclose(fp);
}
//DXアーカイブファイルのメモリへの読み込み
char str[16];
sprintf_s(str, "data%d.dxa", numUseData);
int dataSize = FileRead_size(str);
char *dataImage = (char *)malloc(dataSize);
int dataFile = FileRead_open(str);
FileRead_read(dataImage, dataSize, dataFile);
FileRead_close(dataFile);
//メモリ上のファイルイメージをそのままDXアーカイブファイルとして扱う
if(useDXArcMem){
DXArchiveSetMemImage((void *)dataImage, dataSize, "data.dxa");
}
//メモリ上のファイルイメージをDXアーカイブファイルとして吐き出す
else{
fopen_s(&fp, "data.dxa", "wb");
fwrite(dataImage, 1, dataSize, fp);
fclose(fp);
}
//問題の箇所
int File = FileRead_open("data\\a.txt");
FileRead_close(File);
//(忘れていたので追加しました)
//アーカイブとして扱っていたメモリ上のファイルイメージを解放する
if(useDXArcMem){
DXArchiveReleaseMemImage(dataImage);
}
//(忘れていたので追加しました)
free(dataImage);
dataImage = NULL;
DxLib_End();
fopen_s(&fp, "data.dxa", "r");
if(fp != NULL){
fclose(fp);
remove("data.dxa");
}
fopen_s(&fp, "output.txt", "a");
if(fp != NULL){
fprintf_s(fp, "処理が完了しました\n");
fclose(fp);
}
return 0;
}
//end
ついでに、以前 DxArchiveSetMemImage と SetDxArchiveArchiveExtension を併用した場合にうまく動作しなかった記憶があります。
詳しくは覚えておらず申し訳ないのですが一応報告しておきます