DLL skompilowany ze źródeł nie działa

0

W skrócie: Plik DLL skompilowany ze źródeł nie działa z moim programem. Plik DLL dostarczony przez autora biblioteki działa poprawnie. W czym tkwi błąd?

Dłuższa wersja: Piszę program korzystający z biblioteki HLLib służącej do wypakowywania plików GCF (używane przez gry na Steamie) -

http://nemesis.thewavelength.net/index.php?p=35

Ma ona otwarte źródła, więc postanowiłem do swojego repozytorium dołączyć ją w takiej właśnie postaci zamiast binarnych plików DLL i LIB.

Niestety, plik DLL, który otrzymuję po kompilacji, nie działa poprawnie z moim programem. Wprowadziłem w bibliotece tylko kilka zmian polegających na rzutowaniu argumentów funkcji, aby pozbyć się błędów kompilacji, ale nie wiem, czy to one mogą być winne. Kompilowałem za pomocą MinGW z poziomu QtCreatora, który tworzył pliki Makefile.

Za to używając pliku DLL dostarczonego przez autora HLLib, mój program działa poprawnie. Czy ktoś ma pomysł jak można to naprawić? Źródła do mojego programu są dostępne tutaj -

http://dl.getdropbox.com/u/649112/TF2HC%204programers.zip

jeśli ktoś chce samą bibliotekę, to jest tutaj -
http://nemesis.thewavelength.net/files/files/hllib211.zip

Dołączyłem także plik DLL od autora biblioteki, który zajmuje 220 KB, chociaż ja otrzymywałem 169 KB po kompilacji (nie wiem, czy to ma znaczenie).

Z góry dzięki! :)

0

nie działa poprawnie
Czyli?

Wprowadziłem w bibliotece tylko kilka zmian polegających na rzutowaniu argumentów funkcji, aby pozbyć się błędów kompilacji
Wątpię, aby ktoś dostarczał open-source'owy kod który się nie kompiluje (chodź nie wykluczam).

To były błędy czy warningi? Jeśli warningi, to czy DLL bez wprowadzania żadnych zmian po kompilacji działa OK? Jeśli tak, to coś sknociłeś wprowadzając zmiany.

Może użyłeś złego kompilatora lub złych opcji kompilatora? Autorzy biblioteki powinni coś na ten temat napisać.

0
adf88 napisał(a)

nie działa poprawnie
Czyli?

Biblioteka służy do wypakowywania plików z archiwum GCF. Mówiąc "nie działa" miałem na myśli, że po uruchomieniu przerobionego programu HLExtract (tego samego autora) i podaniu mu odpowiednich argumentów (lokalizacja pliku GCF, folder wyjściowy i pliki do wypakowania), program się kończy z błędem, że nie udało się otworzyć archiwum.

Dokładnie to jest to następujący kod w pliku packageextract.cpp:

        // Open the package.
        // Of the above modes, only HL_MODE_READ is required.  HL_MODE_WRITE is present
        // only for future use.  File mapping is recommended as an efficient way to load
        // packages.  Quick file mapping maps the entire file (instead of bits as they are
        // needed) and thus should only be used in Windows 2000 and up (older versions of
        // Windows have poor virtual memory management which means large files won't be able
        // to find a continues block and will fail to load).  Volatile access allows HLLib
        // to share files with other applications that have those file open for writing.
        // This is useful for, say, loading .gcf files while Steam is running.
        if(!hlPackageOpenFile(lpPackage, uiMode))
        {   qDebug() << "  koniec w open file";
                Print(FOREGROUND_RED | FOREGROUND_INTENSITY, "Error loading %s:\n%s\n", lpPackage, hlGetString(HL_ERROR_SHORT_FORMATED));

                hlShutdown();
                return 3;
        }

Zaznaczam jeszcze raz, że podmianie DLLa na ten od autora wszystko działa poprawnie.

Wprowadziłem w bibliotece tylko kilka zmian polegających na rzutowaniu argumentów funkcji, aby pozbyć się błędów kompilacji

adf88 napisał(a)

Wątpię, aby ktoś dostarczał open-source'owy kod który się nie kompiluje (chodź nie wykluczam).

To były błędy czy warningi? Jeśli warningi, to czy DLL bez wprowadzania żadnych zmian po kompilacji działa OK? Jeśli tak, to coś sknociłeś wprowadzając zmiany.

Może użyłeś złego kompilatora lub złych opcji kompilatora? Autorzy biblioteki powinni coś na ten temat napisać.

To były błędy. Powodowały one przerwanie kompilacji, dlatego musiałem je naprawić. Zamieszczam listę zmian, które wprowadziłem:

zmiany w HLLib:

- Error.cpp, line 125
było: 	if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, this->uiSystemError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&lpMessage, 0, NULL))
jest: 	if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, this->uiSystemError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ((WCHAR*)((LPSTR)&lpMessage)), 0, NULL))

- FileMapping.cpp, line 84
było: 	this->hFile = CreateFile(this->lpFileName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
jest: 	this->hFile = CreateFile(((const WCHAR*)(this->lpFileName)), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);

- FileStream.cpp, line 75
było: 	this->hFile = CreateFile(this->lpFileName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
jest: 	this->hFile = CreateFile(((const WCHAR*)(this->lpFileName)), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);

- Utility.cpp, line 18
było: 	HANDLE Handle = FindFirstFile(lpPath, &FindData);
jest: 	HANDLE Handle = FindFirstFile((const WCHAR*)lpPath, &FindData);

- Utility.cpp, line 46
było: 	HANDLE Handle = FindFirstFile(lpPath, &FindData);
jest: 	HANDLE Handle = FindFirstFile((const WCHAR*)lpPath, &FindData);

- Utility.cpp, line 76
było: 	HANDLE Handle = FindFirstFile(lpPath, &FindData);
jest: 	HANDLE Handle = FindFirstFile((const WCHAR*)lpPath, &FindData);

- Utility.cpp, line 104
było: 	return CreateDirectory(lpPath, 0) != FALSE || GetLastError() == ERROR_ALREADY_EXISTS;
jest: 	return CreateDirectory((const WCHAR*)lpPath, 0) != FALSE || GetLastError() == ERROR_ALREADY_EXISTS;

Warningów nie chciało mi się naprawiać, bo było ich ponad 200 i głównie dotyczyły braku obsługi pewnych wartości enum w switchach, czyli rzeczy nie wpływających na pracę aplikacji.

Do biblioteki były dołączone makefile'e dla G++, ale w wersji na Linuxa, oraz dla Visual Studio 8 i 9. Gdy przepisałem flagi do pliku .pro w QtCreatorze, wyrzucało błędy albo ostrzeżenia, że je zignorowało. W dodatku, QtCreator (a dokładnie qmake) tworzył własny plik Makelife.

Oryginalny Makefile dla Linuxa wygląda tak:

CXX		=	g++
HLLIB_VERS	=	2.0.10
LDFLAGS		=	-shared -Wl,-soname,libhl.so.2
CXXFLAGS	=	-O2 -g -fpic -funroll-loops -fvisibility=hidden
PREFIX		=	/usr/local
sources		=	BSPFile.cpp Checksum.cpp DebugMemory.cpp DirectoryFile.cpp \
			DirectoryFolder.cpp DirectoryItem.cpp Error.cpp FileMapping.cpp \
			FileStream.cpp GCFFile.cpp GCFStream.cpp HLLib.cpp \
			Mapping.cpp MappingStream.cpp MemoryMapping.cpp MemoryStream.cpp \
			NCFFile.cpp NullStream.cpp PAKFile.cpp Package.cpp ProcStream.cpp \
			Stream.cpp StreamMapping.cpp Utility.cpp VBSPFile.cpp VPKFile.cpp \
			WADFile.cpp Wrapper.cpp XZPFile.cpp ZIPFile.cpp
objs		=	$(sources:.cpp=.o)

.cpp.o:
	$(CXX) -c $(CXXFLAGS) -o $@ $<

all: libhl.so.$(HLLIB_VERS)

clean:
	rm -f \#* *~ *.o *.so.*

install: libhl.so.$(HLLIB_VERS)
	install -g root -m 0755 -o root -d $(PREFIX)/lib $(PREFIX)/include
	install -g root -m 0644 -o root libhl.so.$(HLLIB_VERS) $(PREFIX)/lib
	install -g root -m 0644 -o root ../lib/HLLib.h $(PREFIX)/include/hl.h
	ln -fs $(PREFIX)/lib/libhl.so.$(HLLIB_VERS) $(PREFIX)/lib/libhl.so.2
	ln -fs $(PREFIX)/lib/libhl.so.$(HLLIB_VERS) $(PREFIX)/lib/libhl.so

libhl.so.$(HLLIB_VERS): $(objs)
	$(CXX) $(LDFLAGS) -o $@ $(objs)
</quote>
0
this->hFile = CreateFile(((const WCHAR*)(this->lpFileName)), ...);

Przy założeniu, że lpFileName to ansi-string, to takie rzutowanie wskaźnika char* na WCHAR*/wchar_t* nie jest jednoznaczne z konwersją ansi -> unicode. To jest błąd. Opcje masz dwie: skompilować projekt w trybie ANSI lub wywoływać funkcje WinAPI z jawnie określoną wersją ANSI/UNICODE, np.: CreateFileA/CreateFileW

1 użytkowników online, w tym zalogowanych: 0, gości: 1