Явное связывание библиотеки динамической загрузки и заблуждение во время выполнения - PullRequest
0 голосов
/ 26 марта 2019

Я работал с DLL в Windows. Я создал один из них, а также я могу успешно связать свою клиентскую программу с DLL. Но у меня есть неправильное представление. Когда я читал о DLL, была цитата, которая подчеркивалась, когда DLL загружалась в память, все экземпляры программы могли использовать ее. поэтому это приводит к тому, что мы эффективно используем память, а дублирование кода никогда не происходило.

Итак, я пишу программу, и она может успешно загрузить DLL и использовать ее. Когда программа работала, я выполнил образец предыдущей программы по другому пути, которого там нет, но DLL, когда я запускаю вторую программу, показывает ошибку, DLL не загружается.

Мое предположение было, когда первая программа загружает DLL в память, поэтому один ее экземпляр существует в памяти, поэтому я должен использовать его снова, но этого не происходит. Итак, я хотел знать, как несколько программ могут использовать экземпляр DLL? Как мне реализовать пример для проверки этого поведения? Должна ли программа иметь образец DLL в своем пути?

Извините, что плохо говорю по-английски. Должен отметить, что я начинающий программист, а не профессионал. Извините, если вы нашли этот вопрос настолько глупым. Это мой код:

Program.cpp

#include <Windows.h>
#include <iostream>
#include <string>

typedef void(__cdecl *PtrSetInformation)(std::string, std::string, int);
typedef void(__cdecl *PtrShowInformation)(void);

auto main() -> int {
    HINSTANCE HandlerInstance = LoadLibrary(TEXT("LibEngine.dll"));

    if (!HandlerInstance) {
        std::cout << "DLL doesn't load successfuly." << std::endl;
    }
    else {
        std::cout << "Dll is loaded successfuly." << std::endl;
    }

    PtrSetInformation OSetInformation = reinterpret_cast<PtrSetInformation>(GetProcAddress(HandlerInstance, "SetInformation"));
    PtrShowInformation OShowInformation = reinterpret_cast<PtrShowInformation>(GetProcAddress(HandlerInstance, "ShowInformation"));

    if (!OSetInformation || !OShowInformation) {
        std::cout << "Function pointers doesn't initiliazed successfuly." << std::endl;
    }
    else {
        OSetInformation("Mikhail", "Razborov", 24);
        OShowInformation();
    }

    std::cin.get();

    return 0;
}

Мой код DLL:

#include <iostream>
#include <string>

std::string __name;
std::string __family;
int __age;

extern "C" {
    __declspec(dllexport) void __cdecl SetInformation(std::string arg_name, std::string arg_family, int arg_age) {
        __name = arg_name;
        __family = arg_family;
        __age = arg_age;
    }

    __declspec(dllexport) void __cdecl ShowInformation() {
        std::cout << "Your name is " << __name << " " << __family << std::endl;
        std::cout << "You are a " << __age << " year old programmer." << std::endl;
    }
}

1 Ответ

0 голосов
/ 26 марта 2019

Несмотря на то, что образ DLL в памяти может быть общим (это не всегда), Windows по-прежнему необходим доступ к копии на диске при загрузке .exe.Это связано с тем, что у вас могут быть две разные библиотеки DLL с одинаковыми именами в разных каталогах, и Windows рассматривает каждую из них как отдельную сущность.

Появление рандомизации макета адресного пространства (ASLR) сместило цель в отношенииКод DLL, разделяемый между процессами.Раймонд Чен широко об этом писал, например, здесь .

...