在将项目从vs2008移动到vs2015时,我陷入了VS2015 libc中的一个错误。 问题是在对位置X执行fseek操作之后,fread从X + 10开始读取数据。
在fseek操作返回有人看守的位置后,没有引发错误,ftell调用,但是fread不会在有人看见的位置开始。而且,它取决于之前的fseek / fread操作。
使用VS2008(32或64位)运行时不存在此问题,并且在使用VS2015(32或64位)运行时出现此问题。
感谢任何想法提前!!
二进制文件可用here。 示例代码:
#include <fstream>
#include <iostream>
#include <iomanip>
#include <windows.h>
bool foo(FILE *f, unsigned char *buffer, int seek_to, int read_bytes)
{
size_t res = 0;
std::cout << "\tSeek to " << seek_to << std::endl;
// issue present if using fseek or _fseeki64
if (fseek(f, seek_to, SEEK_SET) != 0)
{
std::cout << "\tFAILED" << std::endl;
return false;
}
std::cout << "\tRead " << read_bytes << " bytes" << std::endl;
if ((res = fread(buffer, 1, read_bytes, f)) != read_bytes)
{
std::cout << "\tFAILED, " << res << "bytes readen" << std::endl;
return false;
}
return true;
}
// issue is present in 32 and 64bits of VS2015 update 3
int main(int argc, char **argv)
{
// open the AVC binary file
FILE *favc = fopen(argv[1], "rb");
// big buffer
unsigned char *buffer = new unsigned char[1024*1024];
// step 1, seek and read
std::cout << "Step 1" << std::endl;
foo(favc, buffer, 35026374, 7730);
std::cout << "Step 2" << std::endl;
foo(favc, buffer, 35030470, 8192);
// failing reading, buffer should start with 00 00 00 01 09
std::cout << "Step 3 - where all failed" << std::endl;
foo(favc, buffer, 35034577, 16428);
std::cout << "Buffer: '";
for (size_t i = 0; i < 5; ++i) std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)buffer[i];
std::cout << "'" << std::endl;
unsigned int v = *((unsigned int*)(buffer+1));
if (v != 0x09010000) std::cout << "ISSUE DETECTED" << std::endl;
return 0;
}
答案 0 :(得分:1)
问题被确认为VC8 Redist 2015在SDK8.1目标上的错误。 请参阅此处的错误跟踪:https://connect.microsoft.com/VisualStudio/feedback/details/3133357
解决方法是: - 不要使用fopen / fread / fseek函数,首选WIN32 API CreateFile / ... - 目标Windows 10(不是带有SDK8.1的7)