gpt4 book ai didi

c# - 通过 DllImport 调用非托管函数时堆损坏

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:44:07 26 4
gpt4 key购买 nike

我正在使用 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 数组的指针。

关于c# - 通过 DllImport 调用非托管函数时堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25164170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com