检测到缓冲区溢出
Buffer overrun detected
当我使用C#DllImport C++dll时,我有一个问题,我使用visual studio 2010&选中"启用非托管代码调试",运行时始终显示消息"检测到缓冲区溢出!…检测到缓冲区时溢出已损坏程序的内部状态。程序无法安全地继续执行,必须立即终止。">
这个dll是第三方供应商提供的,他们说运行这个dll没有错误,我该如何修复它?
我的M++dll函数是,
int avc_to_avi_convert(char* chPath_avc, char* chPath_avi, int pPrivate, PROGRESS_CALLBACK progress_callback);
void avc_to_avi_close(int* pFd_avi);
typedef void (*PROGRESS_CALLBACK)(int iPercent, int pPrivate);
我在我的C#dllimport中使用它,如下所示:
public delegate void PROGRESS_CALLBACK(int _iPercent, int _pPrivate);
[DllImportAttribute(@"..xxx.dll", EntryPoint = "avc_to_avi_convert", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern unsafe int avc_to_avi_convert([MarshalAs(UnmanagedType.LPStr)] StringBuilder _inputAVC, [MarshalAs(UnmanagedType.LPStr)] StringBuilder _ouputAVI, int pPrivate, PROGRESS_CALLBACK _pg);
[DllImportAttribute(@"..xxx.dll", EntryPoint = "avc_to_avi_close", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern unsafe void avc_to_avi_close(int pFd_avi);
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
StringBuilder inputFile = new StringBuilder(Application.StartupPath + @"avcabc.avc");//(@"C:avcabc.avc");
StringBuilder outputFile = new StringBuilder(Application.StartupPath + @"aviabc.avi");//(@"C:aviabc.avi");
if (avc_to_avi_convert(
inputFile,
outputFile,
1,
progress_func) > 0) {
}
}
public void progress_func(int iProgress, int pPrivate)
{
if (iProgress == 100)
{
//success
}
else if (iProgress == -1)
{
//convert error
}
else if (iProgress == -2)
{
//Not enough disk space
}
else
{
//update progress
}
}
我把代码改成了
[DllImportAttribute(@"..xxx.dll", EntryPoint = "avc_to_avi_convert", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
public static extern unsafe int avc_to_avi_convert([MarshalAs(UnmanagedType.BStr)] String _inputAVC, [MarshalAs(UnmanagedType.BStr)] String _ouputAVI, int pPrivate, PROGRESS_CALLBACK _pg);
[DllImportAttribute(@"..xxx.dll", EntryPoint = "avc_to_avi_close", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
public static extern void avc_to_avi_close(ref int avi);
然后运行它,我仍然会遇到同样的错误。
1.)您确定调用约定吗?尝试CallingConvention.StdCall
。阅读:
http://blogs.msdn.com/b/adam_nathan/archive/2003/05/21/56690.aspx
2.)为CharSet
属性尝试不同的值,并使用String
而不是StringBuilder
作为路径参数。这是一个很好的参考:
http://msdn.microsoft.com/en-us/library/s9ts558h.aspx
3.)此外,avc_to_avi_close
方法应该如下所示:
[DllImportAttribute("xxx.dll", EntryPoint="avc_to_avi_close")]
public static extern void avc_to_avi_close(ref int avi);
4.)你我想试试的其他东西:
- 使用
CharSet
和MarshalAs
的异常组合。例如,您从上面的链接中知道Unicode
应该与LPWStr
一起使用,Ansi
应该与LPStr
一起使用,但您当然可以尝试其他组合 - 您的extern方法不需要标记为
unsafe
如果你已经用尽了所有其他选项,为什么不尝试编写一个类似于你的C#代码的C++程序:
- 如果它崩溃,则证明错误在库中
- 如果它没有崩溃,你就知道这个错误是在你使用PInovke的过程中,你可以逐一查看我答案中的所有12+组合
您将委托传递给p/invoke,然后让垃圾收集器释放它。这会导致崩溃,因为当委托对象最终确定时,为允许来自本机代码的调用而设置的蹦床会被释放。然后,本机代码调用一个悬空函数指针。
垃圾收集器完全不知道本机代码中使用的任何对象。您必须在通话期间保持对代理的引用有效。尝试添加一个委托变量(不要使用创建临时变量的隐式转换),然后使用GCHandle
使委托在本地代码使用期间保持活动状态。
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 使用 strcat 获取缓冲区溢出错误
- LeetCode 1:两和 - 地址清理器:堆缓冲区溢出地址
- 使用向量的缓冲区溢出
- 重新增长阵列时出错:写入时缓冲区溢出
- Leetcode 1366:堆缓冲区溢出
- 缓冲区溢出 - 数组索引越界(严重)
- C++二维矢量导致缓冲区溢出
- 缓冲区溢出怎么会成为黑客的攻击
- 如何防止缓冲区溢出
- 应该如何读取堆缓冲区溢出错误消息?
- 自动截断和 null 终止缓冲区溢出中的字符串缓冲区
- 如果用户输入两个或多个由空格分隔的字符串C++如何防止缓冲区溢出?
- MSVC C6029 警告:缓冲区可能溢出,使用未经检查的值.检查缓冲区大小时,警告不会消失
- 我正在尝试使用回溯来解决 N queen 问题,但在编译时它会给出运行时错误(动态堆栈缓冲区溢出)
- 我不能溢出缓冲区
- 包含溢出缓冲区的堆栈分配变量,也称为缓冲区
- STL矢量溢出缓冲区