追記、
VC6.0の_splitpathってUNICODE大丈夫ですか?
存知の方お願いします。
VC2005は大丈夫ですね。
ご報告。
Dll側
extern C BOOL PASCAL EXPORT ExportedFunction(char *name)
{
CString strString = _T(C:\\DATA\\表.txt) ;
// ファイル名を取り出す
CString strDrive ;
CString strDir ;
CString strFName ;
CString strExt ;
CString strData = strString ;
_splitpath( strString, strDrive.GetBuffer( _MAX_DRIVE ),
strDir.GetBuffer( _MAX_DIR ), strFName.GetBuffer( _MAX_FNAME ),
strExt.GetBuffer( _MAX_EXT ) ) ;
strDrive.ReleaseBuffer() ;
strDir.ReleaseBuffer() ;
strFName.ReleaseBuffer() ;
strExt.ReleaseBuffer() ;
strcpy(name, strFName);
return TRUE;
}
呼び出し元(exe)
char name[256];
ExportedFunction(name);
AfxMessageBox(name);
結果:Release/Debugどちらも問題なくメッセージボックスに「表」が表示される。
(文字コードはVC6のデフォルトのまま=MBCS)
ということで、提示されている以外のコードに問題がある、に一票。
っていうか TCHAR(=CString) を使うのなら _splitpath など使っちゃダメダメ
_tsplitpath でなきゃ。
_splitpath に char を渡すのであれば問題ない
_wsplitpath に wchar_t を渡すのであれば問題ない
char と wchar_t が混在するのは論外 (今回の提示例のように)
ついでに みかんさん の関数 GetChangeExt で実験
DLL側
CString FAR PASCAL EXPORT GetChangeExt( CString *string, char *ext )
{
// ファイル名を取り出す
CString strDrive ;
CString strDir ;
CString strFName ;
CString strExt ;
_splitpath( *string, strDrive.GetBuffer( _MAX_DRIVE ),
strDir.GetBuffer( _MAX_DIR ), strFName.GetBuffer( _MAX_FNAME), strExt.GetBuffer
( _MAX_EXT ) ) ;
strDrive.ReleaseBuffer() ;
strDir.ReleaseBuffer() ;
strFName.ReleaseBuffer() ;
strExt.ReleaseBuffer() ;
// 拡張子とファイル名をくっつける
CString retSt = _T(") ;
retSt.Format( _T(%s%s%s.%s), strDrive, strDir, strFName/*caFName*/,
ext ) ;/*提示されたコードではコンパイルエラーとなるので変数を変更*/
return( retSt ) ;
}
呼び出し元:
CString strPath = _T(C:\\DATA\\表.txt);
CString changedPath = GetChangeExt(&strPath, INI);
AfxMessageBox(changedPath);
結果:問題なし
補足:
> 結果:問題なし
結果として必要な文字列が得られたということで、プログラムが正しいと言っているわ
けではありません。
正しくは tetrapod さんがおっしゃっているように、char/wchar_t/TCHARに合わせて適
切に関数を使い分ける必要があります。
# いうまでもないことですが。
VC6を使っているという時点で色々突っ込み所はあると思います。
今までのソフトのメンテナンス用と言う話ならわかるんですが、
もし改めて作成しようとしているのであれば、VC6を使うのはどうかなと。
VC6は現状のC++の規格からすると相当古い実装ですから、
今時のC++のサンプルなんかもコンパイル通らなかったりしそうですし。
MFCを使える環境を用意するとなるとお金が掛かるからと言う話で
なおかつ個人でやっていると言うなら仕方ないかなと思いますけれど、
もし仕事でやっているならバージョンアップをしないと結構つらいと思います。
さて、VC6を使っていたとしてもTCHAR、char、WCHAR等の使い分けに関しては
何も変わっていないと思いますから、もしその辺の知識に自身が無いのであれば、
きちんと勉強して確認された方が良いと思います。
ReleaseとDebugで挙動が違うと言うのは基本的に自分のコーディングに
問題がある事が殆どだと思います。
場合によっては別な所でメモリを壊している事が原因だったりする事も
あると思いますから、コードの見直しを考えた方が良いかもしれません。
maruさん、おつかれ様です。
自分も実験してみました(たまたまVC6のPCが空いてた)。
char配列を使いましたが、Releaseモードで正常に「表」が
取れますね。
(余禄)久しぶりに使ってみるとVC6のソースファイルの選択(MDI)が
結構使いづらいし、リリースってどうやって設定するんだったっけ
とかが・・・(vv;)。
> 原因としては表の下位コードが\と同じの5cとなっているというところまでは
_splitpath() 呼ぶ前に
_setmbcp(_MB_CP_OEM);
を入れてみたら? 多分マルチバイト文字関連のコードページがおかしな指定になってん
じゃない?
ただ、これで正常に動いたとしても「何故 Release でのみ症状が起きてるのか」の解説
は俺にはできんが
# プロジェクト設定等も含めて、何処かに”何か”があり其れに起因してるんだろうけど
> CString FAR PASCAL EXPORT GetChangeExt( CString *string, char *ext )
参考: PathRenameExtension() というファイルパスの拡張子を変更するための API が既
存したりする。
今さらですが、VC6の頃、MFCのこんなバグに悩まされたことがあります。
http://win32lab.com/memo/index.cgi?no=12&reno=no&oya=12&mode=msgview&page=0
今回の件と直接は関係がないのですが、参考までに。
様々なコメントありがとうございます。
指摘されているcharやwchar_tの違いについて正確に把握できていなく、勉強不足という
事を痛感いたしました。
ここは勉強し直したいと思います。
問題の発生している部分でCstringをcharしたり色々こちらで試しましたが変化がありま
せんでした。
ただ、_setmbcp(_MB_CP_OEM);
を宣言した所ファイル名を正確に取得する事に成功致しました。
これを元に何故Releaseモードでのみ問題が発生するか引き続き調査して行きたいと思い
ます。
皆様、ご協力ありがとうございました。