ladislav-zezula / StormLib

Official GitHub repository of the StormLib library created by Ladislav Zezula (author)
http://www.zezula.net/mpq.html
MIT License
563 stars 214 forks source link

Issue after move from 6.25 to 9.0 #11

Closed Profforgr closed 10 years ago

Profforgr commented 10 years ago

Hello.

Note: in text 'you' = 'any StormLib developer'.

I am trying to use StormLib 9.0 in application called Ghost++ [ official repo: https://code.google.com/p/ghostplusplus/ ] to better handle MPQ archives (maps for Warcraft III), primary to open protected maps with this application (it`s a Bot for Warcraft III) [ so i need at least 8.0 by this changelog https://github.com/stormlib/StormLib/blob/master/doc/History.txt ]. Previous version 6.25 and it works like a charm for a years. I don't know why i don't see '6.25' in history, maybe it was dev version.

But i have an error in compile process of Ghost++ application [i compiled StormLib and Ghost++ on this machine; i am using Linux Debian, used Makefile.linux file for compilation and i am using gcc version 4.7.2 (Debian 4.7.2-5) compiler]. I have such errors (same) either with 9.0 and current dev version.

Not sure how to fix. Maybe you can make backward compability to this function (if possible)? Or just suggest what should i change, please.

Errors:

In file included from ghost.cpp:27:0:
socket.h:83:13: error: previous declaration of ‘int GetLastError()’ with ‘C++’ linkage
In file included from ghost.cpp:50:0:
/usr/local/include/StormLib/StormLib.h:1104:20: error: conflicts with new declaration with ‘C’ linkage
ghost.cpp: In member function ‘void CGHost::ExtractScripts()’:
ghost.cpp:1564:69: error: too few arguments to function ‘bool SFileReadFile(HANDLE, void*, DWORD, LPDWORD, LPOVERLAPPED)’
In file included from ghost.cpp:50:0:
/usr/local/include/StormLib/StormLib.h:1031:15: note: declared here
ghost.cpp:1591:69: error: too few arguments to function ‘bool SFileReadFile(HANDLE, void*, DWORD, LPDWORD, LPOVERLAPPED)’
In file included from ghost.cpp:50:0:
/usr/local/include/StormLib/StormLib.h:1031:15: note: declared here

About first error:

socket.h:83:13: error: previous declaration of ‘int GetLastError()’ with ‘C++’ linkage
In file included from ghost.cpp:50:0:
/usr/local/include/StormLib/StormLib.h:1104:20: error: conflicts with new declaration with ‘C’ linkage

It looks like, that C++ have such function already and it can not be reused by StormLib... Maybe do something like

void  StormLib_SetLastError(int err);
int   Stormlib_GetLastError();

as a replace of

void  SetLastError(int err);
int   GetLastError();

Just guessing.

About second error:

ghost.cpp: In member function ‘void CGHost::ExtractScripts()’:
ghost.cpp:1564:69: error: too few arguments to function ‘bool SFileReadFile(HANDLE, void*, DWORD, LPDWORD, LPOVERLAPPED)’
In file included from ghost.cpp:50:0:
/usr/local/include/StormLib/StormLib.h:1031:15: note: declared here
ghost.cpp:1591:69: error: too few arguments to function ‘bool SFileReadFile(HANDLE, void*, DWORD, LPDWORD, LPOVERLAPPED)’
In file included from ghost.cpp:50:0:
/usr/local/include/StormLib/StormLib.h:1031:15: note: declared here

I compared lines from StormLib.h:

9.0:

bool   WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped);

6.25:

BOOL  WINAPI SFileReadFile(HANDLE hFile, VOID * lpBuffer, DWORD dwToRead, DWORD * pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL);

As of my very tiny knowledges of C++ it looks like that you make two options 'pdwRead' and 'LPOVERLAPPED' mandatory. It it really must be added for function to work? Maybe change back to something like this?

bool   WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL);

Lines from files mentioned in error output: socket.h:83

extern int GetLastError( );

ghost.cpp:1564

if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )

ghost.cpp:1591

if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )

Full function ExtractScripts() with these two lines:

void CGHost :: ExtractScripts( )
{
    string PatchMPQFileName = m_Warcraft3Path + "War3Patch.mpq";
    HANDLE PatchMPQ;

    if( SFileOpenArchive( PatchMPQFileName.c_str( ), 0, MPQ_OPEN_FORCE_MPQ_V1, &PatchMPQ ) )
    {
        CONSOLE_Print( "[GHOST] loading MPQ file [" + PatchMPQFileName + "]" );
        HANDLE SubFile;

        // common.j

        if( SFileOpenFileEx( PatchMPQ, "Scripts\\common.j", 0, &SubFile ) )
        {
            uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

            if( FileLength > 0 && FileLength != 0xFFFFFFFF )
            {
                char *SubFileData = new char[FileLength];
                DWORD BytesRead = 0;

                if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )
                {
                    CONSOLE_Print( "[GHOST] extracting Scripts\\common.j from MPQ file to [" + m_MapCFGPath + "common.j]" );
                    UTIL_FileWrite( m_MapCFGPath + "common.j", (unsigned char *)SubFileData, BytesRead );
                }
                else
                    CONSOLE_Print( "[GHOST] warning - unable to extract Scripts\\common.j from MPQ file" );

                delete [] SubFileData;
            }

            SFileCloseFile( SubFile );
        }
        else
            CONSOLE_Print( "[GHOST] couldn't find Scripts\\common.j in MPQ file" );

        // blizzard.j

        if( SFileOpenFileEx( PatchMPQ, "Scripts\\blizzard.j", 0, &SubFile ) )
        {
            uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

            if( FileLength > 0 && FileLength != 0xFFFFFFFF )
            {
                char *SubFileData = new char[FileLength];
                DWORD BytesRead = 0;

                if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )
                {
                    CONSOLE_Print( "[GHOST] extracting Scripts\\blizzard.j from MPQ file to [" + m_MapCFGPath + "blizzard.j]" );
                    UTIL_FileWrite( m_MapCFGPath + "blizzard.j", (unsigned char *)SubFileData, BytesRead );
                }
                else
                    CONSOLE_Print( "[GHOST] warning - unable to extract Scripts\\blizzard.j from MPQ file" );

                delete [] SubFileData;
            }

            SFileCloseFile( SubFile );
        }
        else
            CONSOLE_Print( "[GHOST] couldn't find Scripts\\blizzard.j in MPQ file" );

        SFileCloseArchive( PatchMPQ );
    }
    else
        CONSOLE_Print( "[GHOST] warning - unable to load MPQ file [" + PatchMPQFileName + "] - error code " + UTIL_ToString( GetLastError( ) ) );
}

Thanks in advance,

Alex.

Deaod commented 10 years ago

For lines 1564 and 1591, use the following:

if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead, NULL ) )

Im not sure what to do with the other error. I think one the GetLastError() functions has to be renamed to avoid these conflicts.

ladislav-zezula commented 10 years ago

The default parameters in SFileReadFile (and in other APIs) were removed because of moving public StormLib interface to C only. Yes, Deaod's way is correct. As for the problem with GetLastError, I'll try to install Debian and try to reproduce the error. But generally, I think it's problem with C versus C++ declaration.

Profforgr commented 10 years ago

For lines 1564 and 1591, use the following:

if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead, NULL ) )

Oh i am stupid. It works! Thanks.

Im not sure what to do with the other error. I think one the GetLastError() functions has to be renamed to avoid these conflicts.

As for the problem with GetLastError, I'll try to install Debian and try to reproduce the error. But generally, I think it's problem with C versus C++ declaration.

There was a function GetLastError defined in socket.h. It's just only in application i use. You can probably fix it my renaming GetLastError to something, but it'll break compability, so you should not do it.

I changed GetLastError in my application to Socket_GetLastError and now it works :)