c - Hvorfor kan fread () ikke virke (hoppe bytes) under Msys/MinGw?

Indlæg af Hanne Mølgaard Plasc

Problem



Forsøger at bygge Xuggler under Windows. Xuggler er kernens native kodefunktioner indpakket i Java til lydbehandlingsformål (herunder ffmpeg).


Min Windows er x64 Win 7 prof, men alle brugte biblioteker er 32bit. Jeg kører bygge procedure under MinGW/MSys, fra under Msys shell med followinf script:


#!/bin/sh
export JAVA\_HOME=/C/Program Files (x86)/Java/jdk1.6.0\_25
export XUGGLE\_HOME=/C/Xuggler

PATH=$XUGGLE\_HOME/bin:/C/Program Files (x86)/Java/jdk1.6.0\_25/bin:/d/APPS/msysgit/msysgit/bin/git:/D/APPS/MinGW/bin:/bin:/D/APPS/apa    che-ant-1.8.2/bin:/D/Users/Dims/Design/MinGW/Util:$PATH
ant -Dbuild.m64=no run-tests


Ant-mål indeholder nogle tests i slutningen, hvilket giver en fejl. Fejlen følger


 [exec] Running 6 tests..
 [exec] In StdioURLProtocolHandlerTest::testRead:
 [exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:108: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
 [exec] In StdioURLProtocolHandlerTest::testReadWrite:
 [exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:185: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
 [exec] In StdioURLProtocolHandlerTest::testSeek:
 [exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:139: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
 [exec] .
 [exec] Failed 3 of 6 tests
 [exec] Success rate: 50\%
 [exec] FAIL: xugglerioTestStdioURLProtocolHandler.exe


UPDATE 1


Testkode er følgende:


int32\_t totalBytes = 0;
do {
    unsigned char buf[2048];
    retval = handler->url\_read(buf, (int)sizeof(buf));
    if (retval > 0)
         totalBytes+= retval;
} while (retval > 0);
VS\_TUT\_ENSURE\_EQUALS("", 4546420, totalBytes);


Mens url\_read -koden følger:


int
StdioURLProtocolHandler :: url\_read(unsigned char* buf, int size)
{
    if (!mFile)
        return -1;
    return (int) fread(buf, 1, size, mFile);
}


Jeg forstår ikke under hvilke omstændigheder det kan vende tilbage 1042 ?? Kan det være 64 bits spille her på en eller anden måde?


UPDATE 2


Jeg udskrev det filnavn, der blev brugt, og det var


d:/......./../../../test/fixtures/testfile.flv


stien er korrekt, men startet med d:/ ikke med /d/


Kan dette spille en rolle under Msys?


UPDATE 3


Jeg har sammenlignet readen bytes med ægte indhold af testfilen og fundet, at fread () hopper nogle bytes af en eller anden grund. Ved ikke hvilke bytes endnu, sandsynligvis er disse CR/LF


UPDATE 4


Ikke relateret til CR/LF jeg gætter på.


Originale bytes er


46 4C 56 01 05 00 00 00 09 00 00 00 00 12 00 00 F4 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74 61 44 61 74 61 08 00 00 ...


readen bytes er


46 4C 56 15 00 09 00 00 12 00 F4 00 00 00 02 0A 6F 6E 4D 65 74 61 44 61 74 61 80 00 B0 86 47 57 26 17 46 96 F6 E0 40 62 ...


Dette er FLV fil start. Jeg forstår ikke princippet om korruption.


Hvordan kan 01 05 00 00 transformere til bare 15 ???


UPDATE 5


Fil åbning gjort som følger


void
StdioURLProtocolHandlerTest :: testRead()
{
  StdioURLProtocolManager::registerProtocol("test");
  URLProtocolHandler* handler = StdioURLProtocolManager::findHandler("test:foo", 0,0);
  VS\_TUT\_ENSURE("", handler);

  int retval = 0;
  retval = handler->url\_open(mSampleFile, URLProtocolHandler::URL\_RDONLY\_MODE);
  VS\_TUT\_ENSURE("", retval >= 0);

  int32\_t totalBytes = 0;
  printf("Bytes:
");
  do {
     //...


url\_open () funktionen følger:


int StdioURLProtocolHandler :: url\_open(const char *url, int flags)
{
  if (!url || !*url)
    return -1;
  reset();
  const char * mode;

  switch(flags) {
    case URLProtocolHandler::URL\_RDONLY\_MODE:
      mode="r";
      break;
    case URLProtocolHandler::URL\_WRONLY\_MODE:
      mode="w";
      break;
    case URLProtocolHandler::URL\_RDWR\_MODE:
          mode="r+";
          break;
        default:
      return -1;
  }

  // The URL MAY contain a protocol string.  Find it now.
  char proto[256];
  const char* protocol = URLProtocolManager::parseProtocol(proto, sizeof(proto), url);
  if (protocol)
  {
    size\_t protoLen = strlen(protocol);
    // skip past it
    url = url + protoLen;
    if (*url == ':' || *url == ',')
      ++url;
  }
//  fprintf(stderr, "protocol: \%s; url: \%s; mode: \%s
", protocol, url, mode);
  mFile = fopen(url, mode);
  if (!mFile)
    return -1;
  return 0;
}

Bedste reference


Bør rettes i GIT-depotet på tværs af filialen i dag. Jeg vil rulle dette til tip af træ senere i ugen/tidligt i næste uge.


Nu åbner stdio handler alle filer som binære.