それが言うところ問題は_lock_file
内にあるように私には思える:
/*
* The way the FILE (pointed to by pf) is locked depends on whether
* it is part of _iob[] or not
*/
if ((pf >= _iob) && (pf <= (&_iob[_IOB_ENTRIES-1])))
{
/*
* FILE lies in _iob[] so the lock lies in _locktable[].
*/
_lock(_STREAM_LOCKS + (int)(pf - _iob));
/* We set _IOLOCKED to indicate we locked the stream */
pf->_flag |= _IOLOCKED;
}
else
/*
* Not part of _iob[]. Therefore, *pf is a _FILEX and the
* lock field of the struct is an initialized critical
* section.
*/
EnterCriticalSection(&(((_FILEX *)pf)->lock));
「正常な」AはFILE*
がトップの枝に入り、u_fgetfile
から返されたポインタは、下の枝を入力します。ここでは、_FILEX*
であると想定されていますが、これは単に正しくない可能性があります。
ランタイムは、ファイルポインタfb
が_iob
の範囲内にあるかどうかを比較します。しかし、デバッガでは、少なくともリリースビルドではそれがはるかに遠いことがわかります。
u_fgetfile
がちょうどUFILE
構造内に格納されていたFILE*
を返すことを考えると、我々はFILE*
が最初の場所で私たちの構造で終わるかを確認するためにufile.c
でfinit_owner
を検査することができます。このコードを読んだら、リリースビルドでは、_iob
配列の2つの別々のインスタンスがCRTに存在すると仮定しなければならないが、デバッグビルドでは1つのインスタンスしか存在しない。
この問題を回避するには、FILE*
がメインアプリケーションと同じスレッドで作成されていることを確認する必要があります。これを行うには、あなたはそうのように、u_finit
を利用することができます。この後に来たあなたの問題について
FILE* filePointer = fopen("test.txt","r");
UFILE* file = u_finit(filePointer,NULL,"UTF-8");
fseek(filePointer,3,SEEK_SET); // <- won't crash
は
、それがために失敗しただけで、ライブラリ間FILE*
を共有している根本的な問題のように私には思えます彼らはFILE*
のための別の記憶領域を持っています。私はこれを幾分混乱させることがわかりましたが、私は関与しているコンポーネント(そしてWindows Cランタイムコードのスタイルはどちらも役に立ちません)の必要な理解を持っていません。
したがって、FILE*
がICUに割り当てられている場合は、メインアプリケーションでロックすることはできず、その逆もありません(読み取りまたはシークを試みると常にロックが必要になります)。
私が紛失しているこの問題に対する非常に明白な解決策がない限り、あなたのメインアプリケーションでu_fgets()
(またはその他の必要なもの)の動作をエミュレートすることをお勧めします。
私が言うことができるものから 、u_fgets()
はちょうどUChar*
に読み出したデータを変換するには、(あなたがu_fgetConverter()
で取得することができます)UFILE
に保存されているコンバータと、ファイルからデータを読み取るためにfread()
を呼び出し、ucnv_toUnicode()
を使用しています。
動作するように見える1つの方法は、静的にICUをリンクすることです。私はそれがあなたのためのオプションであるかどうかわかりませんが、それは私の最後に問題を解決するようです。
ICU(51.2)の最新リリースをダウンロードし、this helpful scriptでコンパイルしました。私はその後icu-release-static-win32-vs2012
(sicuuc.lib
、sicuio.lib
、sicudt.lib
、sicuin.lib
とのリンク)の図書館とプロジェクトをリンクしました。
今すぐu_fgets()
は、アクセス違反を引き起こさなくなりました。もちろん、今私の.exe
はほぼ23 MBの大きさです。
これをテストしましたが、完全性のためだけです: 'u_fopen( ) 'と' u_fgetfile() 'は' NULL'を返しません、そうではありませんか? – alk
私はそれをテストしました。これはFILE構造のためのicuと私のプログラムとの間の何らかの構造不一致のようです。 – monoceres
'FILE'は' 'で定義されています。両方のビルド(libicu **と** test app)で同じでなければなりません。 32ビットと64ビットのビルドが混在していないことを確認してください。 –
alk