C#アプリケーションからC / C ++で記述されたアンマネージDLLを使用しています。dllから次の関数を使用することに興味があります。
static void StorePath(const std::string& path, wchar_t *out_path,
int *out_path_length){
wcslcpy(out_path, c_str_w(path), *out_path_length);
*out_path_length = path.size();
}
int WINAPI BrowseForDirectory(
int allow_portable, int allow_online,
wchar_t *t_directory, int *e_directory_length,
wchar_t *m_directory, int *m_directory_length){
.
.
. //initializing new forms and checking product keys
StorePath(form->SelectedEDirectory().TopDir(), e_directory,
e_directory_length);
StorePath(form->SelectedMDirectory(), m_directory,
m_directory_length);
}
ヘッダーファイル:
#if defined(_WIN32) && !BUILD_WITHOUT_DLLS &&!defined(ECLIPSE_CBUILDER_WORKAROUNDS)
# if BUILDING_EXPORT_LIBRARY
# define EXPORT_DLL __declspec(dllexport)
# else
# define EXPORT_DLL __declspec(dllimport)
# endif
#else
# define EXPORT_DLL
#endif
extern "C" {
int WINAPI BrowseForDirectory(
int allow_portable, int allow_online,
wchar_t *t_directory, int *e_directory_length,
wchar_t *m_directory, int *m_directory_length)
}
次に、次の手順を実行して、自分の管理対象のC#クラスライブラリでこの関数を呼び出そうとしています。
[DllImport("MyDLL.dll", CharSet = CharSet.Ansi)]
public static extern int BrowseForDirectory(Int32 allowOnline,
Int32 allowPortable,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder eDirectory,
ref Int32 eDirLength,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder mDirectory,
ref Int32 mDirLength);
最後に、次のように呼び出して、C#アプリケーションで使用しようとしています。
var eDir = new StringBuilder(260);
var mDir = new StringBuilder(260);
var eDirLength = eDir.Length;
var mDirLength = mDir.Length;
try
{
var result = Viewer.BrowseForDirectory(1, 1, eDir,
ref eDirLength, mDir, ref mDirLength);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
ただし、ヒープが破損していましたが、STATUS_STACK_BUFFER_OVERRUN(埋め込みブレークポイントに関するもの)が原因でアプリケーションが終了しています。C ++コードを変更することはオプションではありません。適切なリファレンスとアセンブリがあります。
私は何が間違っているのですか?
私が見ることができる問題は、あなたの文字セットが一致しないということです。アンマネージコードはテキストをUTF-16として返しますが、p / invokeはANSIエンコードされたテキストを指定します。p / invokeを次のように変更します。
[DllImport("MyDLL.dll", CharSet = CharSet.Unicode)]
public static extern int BrowseForDirectory(
int allowOnline,
int allowPortable,
StringBuilder eDirectory,
ref int eDirLength,
StringBuilder mDirectory,
ref int mDirLength
);
私はそれc_str_w()
が8ビットでエンコードされた文字列を取り、nullで終了する配列へのポインタを返すと仮定していますwchar_t
。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加