Skocz do zawartości

[c++] Korzystanie z bibliotek .dll


Recommended Posts

Witam. Wpadam do was po dłuższej przerwie. Mam nadzieję, że ktoś pomoże mi to ogarnąć. ;)

 

Dokładnie mam 2 pytania.

 

1. Mam program i napisałem do niego dwie .dll'ki (biblioteki linkowane dynamicznie). Jak na razie program działa tylko wtedy, gdy potrzebne pliki .dll znajdują się w tym samym katalogu. Czy da się zrobić, żeby mój soft szukał ich np. w "wyższym" folderze o nazwie "libraries"?

 

2. Chcę by owe .dll'ki były ładowane tylko w określonych momentach, gdy ich zasoby są potrzebne głównemu programowi. Bo jak na razie, program sprawdza przy starcie czy ich nie ma, a jeśli tak, to wywala coś w stylu "Aplikacja nie została poprawnie uruchomiona. Brakuje MyLib.dll", a chcę by program się normalnie włączał nawet bez nich, tylko w odpowiednich momentach (gdy wykryje brak bibliotek) wypisywał komunikat, że brakuje tego i tego i nie może wykonać żądanej operacji.

 

Z góry dzięki za pomoc.

Link to post
Share on other sites

Drugie mi pomogło - biblioteki ładują się tylko w odpowiednich momentach, ale jeszcze problem z wybraniem własnego podkatalogu dla bibliotek, bo funkcja SetDllDirectory() działa chyba tylko w parze z LoadLibrary() a ja jej nie używam.

 

Wie ktoś jak wyznaczyć własny podkatalog gdzie program ma szukać bibliotek?

Najprościej było by dać jakiś "path" we właściwościach projektu, ale nic nie mogę znaleźć

Link to post
Share on other sites

Nie wiem dokładnie jak tego użyć, więc dałem tą funkcję SetDllDirectory() na samym początku main()

SetDllDirectory(L"C:\MyPath\DLL");

Kompiluje się, ale nie ustawia nowej lokalizacji dla dll'ek.

 

Przekopałem internet, niby znalazłem kilka rozwiązań, np. podanie ścieżki podkatalogu w pliku manifest albo dopisanie czegoś w opcjach projektu czy dodanie #pragma comment() (coś takiego), ale nic z tych rzeczy nie działało.

 

Proszę o pomoc, bo zależy mi żeby nie robić syfu w głównym katalogu z programem tylko wrzucić dll'ki do innego folderu.

Edytowane przez seebeek17
Link to post
Share on other sites
SetDllDirectory(L"C:\MyPath\DLL");

To się nie powinno skompilować poprawnie. "\" jest znakiem specjalnym, musisz wpisać podwójnie w stringu. Sprawdź też, czy funkcja zwraca TRUE/FALSE.

 

Edit: nie jestem pewien, czy to coś zmieni, ale miałem też w pierwszej linijce (przed includami) zdefiniowane:

#define _WIN32_WINNT 0x0502

Edytowane przez Fiber
Link to post
Share on other sites

 

 

Sprawdź też, czy funkcja zwraca TRUE/FALSE.

Zwraca True.

 

 

To się nie powinno skompilować poprawnie. "\" jest znakiem specjalnym, musisz wpisać podwójnie w stringu.

Próbowałem później to:

SetDllDirectory((LPCWSTR)L"C:\\MyPath\\DLL");

i to:

SetDllDirectory(L"C:\\MyPath\\DLL");

I nadal nie chce zastosować wybranej ścieżki do katalogu.

 

 

 

#define _WIN32_WINNT 0x0502

Bez zmian.

Link to post
Share on other sites

1. Znaczy się, że wywala Ci błąd, że nie znalazł DLLki?

2. Masz przy tym włączone dla tej DLL delayload (link z pierwszego posta)?

3. Masz pewność, że przed wywołaniem SetDllDirectory() nie masz żadnego odwołania do żadnej funkcji z DLL?

 

Jeśli pkt 1. odp tak, to wrzuć może w celu debuga jakieś MessageBox przed i po SetDllDirectory(), żeby wiedzieć jaka jest kolejność zdarzeń.

Edytowane przez Fiber
Link to post
Share on other sites

 

 

1. Znaczy się, że wywala Ci błąd, że nie znalazł DLLki?

Nie. Wszystko się ładnie kompiluje.

 

 

2. Masz przy tym włączone dla tej DLL delayload (link z pierwszego posta)?

Mam włączone.

Na wszelki wypadek włączyłem jeszcze wywołanie UAC (dostęp do uprawnień admina), bo czytałem, że niektóre funkcje systemowe mogą się nie wywołać, pomimo pomyślnej kompilacji, ale to chyba nie ma tu nic do rzeczy.

 

 

3. Masz pewność, że przed wywołaniem SetDllDirectory() nie masz żadnego odwołania do żadnej funkcji z DLL?

Dam kawałek kodu jak to u mnie wygląda:

// Dodanie headera z source biblioteki dll
#include "MyDLLH.h"			// MyDLL.dll				( Operations structure )

using namespace MyDllClassSpace;

void main()
{
	SetDllDirectory(L"C:\\MyPath\\DLL");

        // (...)

	// GUI and run other
	MyDllClass::DllFunction();
}

SetDllDirectory() działa chyba tylko w parze z LoadLibrary(), a że dodaję bibliotekę przez (dllexport) to nie mogę tego użyć.

Link to post
Share on other sites

Ad.1

Chodzi mi o to, jak się objawia problem. Czy po uruchomieniu wyskakuje komunikat o nieznalezionej DLL.

 

W sumie jeszcze jedna rzecz, która może pomoże przy autoładowaniu DLL. To jest rozwiązanie, którego ja używałem. W jakimś głównym nagłówku (*.h) używanym wszędzie dodaj te linijki.

#if defined EXPORT_PROJECT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

W projekcie z DLL powinno być zadeklarowane dla kompilatora EXPORT_PROJECT (lub inna nazwa własna taka jak w pierwszej linijce). Można to zrobić w https://msdn.microsoft.com/en-us/library/hhzbb5c8(v=vs.120).aspx- natomiast nie powinno się tego robić dla projektu korzystającego z DLL. I wówczas dla każdej eksportowanej funkcji (lub metody) dodajesz na początku DECLDIR. Wtedy w projekcie DLL funkcje dostaną __declspec(dllexport) zaś w projekcie korzystającym z DLL funkcje dostaną __declspec(dllimport). I kolejna porcja info: https://msdn.microsoft.com/pl-pl/library/3y1sfaz2.aspx

 

 

Zdaje mi się, że to załatwi problem ładowania DLL - ale głowy póki co nie dam za to.

Edytowane przez Fiber
Link to post
Share on other sites

 

 

Chodzi mi o to, jak się objawia problem. Czy po uruchomieniu wyskakuje komunikat o nieznalezionej DLL.

Nie ma. Wcześniej wywalało takie info, ale włączyłem Delay Loaded DLL (coś takiego).

 

Problem z ładowaniem bibliotek już rozwiązany. Ładują się tylko w wybranym momencie, o czym pisałem już w poście wyżej.

 

Teraz tylko potrzebuję ustawić ścieżkę dla .dll'ek do katalogu "wyżej".

Link to post
Share on other sites

 

1. Mam program i napisałem do niego dwie .dll'ki (biblioteki linkowane dynamicznie). Jak na razie program działa tylko wtedy, gdy potrzebne pliki .dll znajdują się w tym samym katalogu. Czy da się zrobić, żeby mój soft szukał ich np. w "wyższym" folderze o nazwie "libraries"?

 

Ehh ludziska... nie łatwiej dopisać "../libraries/" do nazwy .dll'a w LoadLibrary? 8-)

Link to post
Share on other sites

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Odpowiedz w tym wątku...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...