ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-07-08 17:04:48  阅读:301  来源: 互联网

标签:c c-2 visual-studio-2013 pinvoke dllimport


我正在使用一个用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,c-2,visual-studio-2013,pinvoke,dllimport
来源: https://codeday.me/bug/20190708/1404018.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有