[physfs] Getting every instance of overlapping files

Tim Čas darkuranium at gmail.com
Wed Aug 27 09:45:12 EDT 2014


How are you using libphysfs.a? I've often found that linking with just
-lphysfs tends to make MinGW link with the DLL instead of the library.

If you have MSYS, you can also try this to find out if the DLL exports
the symbol (which would indicate that the problem is elsewhere):
$ nm libphysfs.dll | grep openRead

Oh and, I just had a thought --- when you added PHYSFS_openReadMulti,
did you create any new source files? If you did, you have to run cmake
again for it to recognize the new files? It is entirely possible that
it's not compiling in said new file (though that wouldn't quite
explain why the symbol exists in the static library).

On 27 August 2014 15:21, Haydn Harach <hharach at gmail.com> wrote:
> It creates "libphysfs.a", "libphysfs.dll", and "libphysfs.dll.a"
>
> I've tried using both the .dll and the non-.dll version of the .a library,
> they both have the issues.  Interestingly, when using libphysfs.a, it still
> requires libphysfs.dll, even before I started modifying the source code.
>
>
> On Wed, Aug 27, 2014 at 7:17 AM, Tim Čas <darkuranium at gmail.com> wrote:
>>
>> And did you also compile the DLLs, or did you only compile the static
>> (*.a) library? MinGW tends to create one file for static builds (foo.a
>> or libfoo.a) and two files for dynamic builds ({lib,}foo.dll.a and
>> {lib,}foo.dll) --- it seems that you've perhaps only created the
>> static library?
>>
>> On 27 August 2014 13:05, Haydn Harach <hharach at gmail.com> wrote:
>> > Yes, I did replace the dll's.  From what I gather,
>> > `PHYSFS_openReadMulti` is
>> > present in `physfs.a` but not in `physfs.dll`, and `PHYSFS_closeList` is
>> > not
>> > present in `physfs.a` (and presumably not in `physfs.dll`, either).
>> >
>> > I'm compiling both physfs and my app using MinGW-W64.
>> >
>> >
>> > On Wed, Aug 27, 2014 at 3:39 AM, Tim Čas <darkuranium at gmail.com> wrote:
>> >>
>> >> Did you replace the DLLs after compiling? The application might still
>> >> be
>> >> using the old one if you forgot to do that.
>> >>
>> >>
>> >> On 27 August 2014 10:10, Haydn Harach <hharach at gmail.com> wrote:
>> >>>
>> >>> PHYSFS_openReadMulti compiles just fine, but then my app crashes
>> >>> because
>> >>> it can't find it in physfs.dll.  So, it found it in the .a, but not in
>> >>> the
>> >>> .dll?  what am I doing wrong compiling physfs? >.<
>> >>>
>> >>>
>> >>> On Tue, Aug 26, 2014 at 9:51 AM, Haydn Harach <hharach at gmail.com>
>> >>> wrote:
>> >>>>
>> >>>> Now I'm having trouble rebuilding the project.  I'm trying to use a
>> >>>> code::blocks project which I generated with cmake, changing only the
>> >>>> 2 files
>> >>>> (physfs.c and physfs.h).  It compiles and builds just fine, but I'm
>> >>>> getting
>> >>>> "undefined reference to PHYSFS_closeList" now.  What did I do wrong?
>> >>>>
>> >>>>
>> >>>> On Mon, Aug 25, 2014 at 6:55 PM, Haydn Harach <hharach at gmail.com>
>> >>>> wrote:
>> >>>>>
>> >>>>> Alrighty, here are the additions I've made to my physfs.c:
>> >>>>>
>> >>>>> PHYSFS_File **PHYSFS_openReadMulti(const char *_fname)
>> >>>>> {
>> >>>>>     char *fname;
>> >>>>>     size_t len;
>> >>>>>
>> >>>>>     BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
>> >>>>>     len = strlen(_fname) + 1;
>> >>>>>     fname = (char *) __PHYSFS_smallAlloc(len);
>> >>>>>     BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
>> >>>>>
>> >>>>>     FileHandle** ret = NULL;
>> >>>>>     unsigned int retcount = 0;
>> >>>>>
>> >>>>>     if (sanitizePlatformIndependentPath(_fname, fname))
>> >>>>>     {
>> >>>>>         int fileExists = 0;
>> >>>>>         DirHandle *i = NULL;
>> >>>>>         fvoid *opaque = NULL;
>> >>>>>
>> >>>>>         __PHYSFS_platformGrabMutex(stateLock);
>> >>>>>
>> >>>>>         GOTO_IF_MACRO(!searchPath, ERR_NO_SUCH_PATH, openReadEnd);
>> >>>>>
>> >>>>>         /* !!! FIXME: Why aren't we using a for loop here? */
>> >>>>>         i = searchPath;
>> >>>>>
>> >>>>>         do
>> >>>>>         {
>> >>>>>             char *arcfname = fname;
>> >>>>>             if (verifyPath(i, &arcfname, 0))
>> >>>>>             {
>> >>>>>                 opaque = i->funcs->openRead(i->opaque, arcfname,
>> >>>>> &fileExists);
>> >>>>>                 if (opaque)
>> >>>>>                 {
>> >>>>>                    // We found a valid file, let's prepare it.
>> >>>>>                    FileHandle* h =
>> >>>>> (FileHandle*)allocator.Malloc(sizeof(FileHandle));
>> >>>>>                    if (h == NULL)
>> >>>>>                    {
>> >>>>>                       i->funcs->fileClose(opaque);
>> >>>>>                         GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
>> >>>>>                    }
>> >>>>>                    memset(h, 0, sizeof(FileHandle));
>> >>>>>                    h->opaque = opaque;
>> >>>>>                    h->forReading = 1;
>> >>>>>                    h->dirHandle = i;
>> >>>>>                    h->funcs = i->funcs;
>> >>>>>                    h->next = openReadList;
>> >>>>>                    openReadList = h;
>> >>>>>
>> >>>>>                      // Add the file to the list
>> >>>>>                      FileHandle** temp =
>> >>>>> (FileHandle**)allocator.Malloc(sizeof(FileHandle) * (retcount + 1));
>> >>>>>                      if (temp == NULL)
>> >>>>>                      {
>> >>>>>                         allocator.Free(h);
>> >>>>>                         i->funcs->fileClose(opaque);
>> >>>>>                         GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
>> >>>>>                      }
>> >>>>>                      if (ret != NULL)
>> >>>>>                      {
>> >>>>>                         memcpy(temp, ret, sizeof(FileHandle) *
>> >>>>> retcount);
>> >>>>>                         allocator.Free(ret);
>> >>>>>                      }
>> >>>>>                      temp[retcount] = h;
>> >>>>>                      ++retcount;
>> >>>>>                      ret = temp;
>> >>>>>                 }
>> >>>>>             } /* if */
>> >>>>>             i = i->next;
>> >>>>>         } while ((i != NULL) && (!fileExists));
>> >>>>>
>> >>>>>         // Add a null terminator to the list
>> >>>>>         if (ret != NULL)
>> >>>>>         {
>> >>>>>            FileHandle** temp =
>> >>>>> (FileHandle**)allocator.Malloc(sizeof(FileHandle) * (retcount + 1));
>> >>>>>            if (temp == NULL)
>> >>>>>                GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
>> >>>>>
>> >>>>>             memcpy(temp, ret, sizeof(FileHandle) * retcount);
>> >>>>>             allocator.Free(ret);
>> >>>>>
>> >>>>>             temp[retcount] = NULL;
>> >>>>>             ret = temp;
>> >>>>>         }
>> >>>>>
>> >>>>>         openReadEnd:
>> >>>>>         __PHYSFS_platformReleaseMutex(stateLock);
>> >>>>>     } /* if */
>> >>>>>
>> >>>>>     __PHYSFS_smallFree(fname);
>> >>>>>     return ret;
>> >>>>> } /* PHYSFS_openReadMulti */
>> >>>>>
>> >>>>> int PHYSFS_closeList(PHYSFS_file** list)
>> >>>>> {
>> >>>>>    int retval = 1;
>> >>>>>
>> >>>>>    for (PHYSFS_file** i = list; *i != NULL; ++i)
>> >>>>>    {
>> >>>>>       if (PHYSFS_close(*i) == 0)
>> >>>>>          retval = 0;
>> >>>>>    }
>> >>>>>
>> >>>>>    allocator.Free(list);
>> >>>>>    return retval;
>> >>>>> }
>> >>>>>
>> >>>>> Is there anything not immediately obvious that I'm missing?
>> >>>>>
>> >>>>>
>> >>>>> On Mon, Aug 25, 2014 at 6:11 PM, Edward Rudd <urkle at outoforder.cc>
>> >>>>> wrote:
>> >>>>>>
>> >>>>>> On Aug 25, 2014, at 8:06 PM, Haydn Harach <hharach at gmail.com>
>> >>>>>> wrote:
>> >>>>>>
>> >>>>>> > Looking at PHYSFS_openRead() in physfs.c, I've found this little
>> >>>>>> > snippet:
>> >>>>>> >
>> >>>>>> > do
>> >>>>>> >         {
>> >>>>>> >             char *arcfname = fname;
>> >>>>>> >             if (verifyPath(i, &arcfname, 0))
>> >>>>>> >             {
>> >>>>>> >                 opaque = i->funcs->openRead(i->opaque, arcfname,
>> >>>>>> > &fileExists);
>> >>>>>> >                 if (opaque)
>> >>>>>> >                     break;
>> >>>>>> >             } /* if */
>> >>>>>> >             i = i->next;
>> >>>>>> >         } while ((i != NULL) && (!fileExists));
>> >>>>>> >
>> >>>>>> > Now, from what I can see, this loop goes through all the paths,
>> >>>>>> > and
>> >>>>>> > the first one that satisfies the function and returns some data
>> >>>>>> > (from the
>> >>>>>> > openRead function) and causes 'opaque' to not be NULL, and thus
>> >>>>>> > breaks out
>> >>>>>> > of the loop.
>> >>>>>> >
>> >>>>>> > So, if I replaced "if (opaque) break;" with "if (opaque)
>> >>>>>> > someVector.emplace_back(opaque, i);", then did some cleanup to
>> >>>>>> > ensure that I
>> >>>>>> > have a vector of FileHandle's instead of one, and return that,
>> >>>>>> > this should
>> >>>>>> > be exactly what I'm looking for, yes?
>> >>>>>>
>> >>>>>> More or less, yes that would be exactly what you were looking for.
>> >>>>>> _______________________________________________
>> >>>>>> physfs mailing list
>> >>>>>> physfs at icculus.org
>> >>>>>> http://icculus.org/mailman/listinfo/physfs
>> >>>>>
>> >>>>>
>> >>>>
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> physfs mailing list
>> >>> physfs at icculus.org
>> >>> http://icculus.org/mailman/listinfo/physfs
>> >>>
>> >>
>> >>
>> >> _______________________________________________
>> >> physfs mailing list
>> >> physfs at icculus.org
>> >> http://icculus.org/mailman/listinfo/physfs
>> >>
>> >
>> >
>> > _______________________________________________
>> > physfs mailing list
>> > physfs at icculus.org
>> > http://icculus.org/mailman/listinfo/physfs
>> >
>> _______________________________________________
>> physfs mailing list
>> physfs at icculus.org
>> http://icculus.org/mailman/listinfo/physfs
>
>
>
> _______________________________________________
> physfs mailing list
> physfs at icculus.org
> http://icculus.org/mailman/listinfo/physfs
>


More information about the physfs mailing list