Как передать аргументы для инициализации DLL (например, при загрузке через LoadLibrary)? - PullRequest
3 голосов
/ 15 апреля 2011

Как можно передать аргументы в функцию инициализации DLL, загруженной через LoadLibrary?Это вообще возможно?Не прибегая к какой-либо экспортируемой функции или разделяемой памяти, то есть.

Ответы [ 4 ]

3 голосов
/ 15 апреля 2011

Прямого пути нет.

Самым простым может быть использование переменных окружения.Их можно легко установить перед вызовом LoadLibray с помощью setenv, а затем DLL (в том же процессе) может получить их с помощью getenv.

0 голосов
/ 03 октября 2013

Другое возможное решение: создайте вторую DLL, которая предоставляет только метод "setparam" и "getparam", чем использовать его как в приложении (setparam), так и в dll DllMain (getparam).В своей основной форме методы реализованы со статическими переменными, но вы можете использовать более сложные технологии.Это решение, хотя и несколько более сложное, имеет некоторые преимущества:

  • оно не использует никаких «глобальных» соглашений (кроме имени общей библиотеки DLL!)

  • он не потребляет возможно ограниченные ресурсы (например, переменные окружения)

  • это общее правило: вы можете использовать одну и ту же библиотеку DLL в любом месте.

  • он может быть сделан настолько мощным и сложным, насколько вам нужно: например, вы можете сделать его поточно-ориентированным при необходимости.Это только вопрос реализации.

Вот минимальный пример:

// The "helper" DLL //
static int param;
void setparam(int v) { param = v; }
int getparam(void) { return param; }

// The application //
setparam(12345);
LoadLibrary("TheDLL.dll");

// The DLL to which you want to pass parameters //
BOOL WINAPI DllMain(HINSTANCE h,DWORD re,LPVOID res)
{
int param;
  switch (re)
  {
  case DLL_PROCESS_ATTACH:
     param = getparam();
//...
0 голосов
/ 09 ноября 2012

Альтернативное средство

Хотя я не совсем уверен, относится ли это к «разделяемой памяти» (поскольку вы также можете использовать этот метод для отправки данных в библиотеки DLL, загруженные также в отдельные процессы) ..Вы можете выделить некоторую память по определенному адресу, используя VirtualAllocEx, передать структуру, содержащую все данные, которые необходимы DLL, используя WriteProcessMemory, а затем заблокировать ее с помощью VirtualLock перед загрузкой DLL.

Затем в функции точки входа DLL я бы использовал VirtualUnlock, чтобы получить эти данные, используя ReadProcessMemory, затем VirtualFree для очистки ресурсов.

Хотя это немного изменчиво, это особенно полезно, если у вас есть не просто простая строка для передачи.Обратите внимание, что вы должны иметь права на чтение / запись в целевом процессе, чтобы это работало.

Пример (псевдокод)

// YourApp.cpp

struct DataToSend {
    int myInt;
    char myStr[320];
};
DataToSend m_data = { 1337, "This is a test string...\0" };

// ...
PVOID remoteData = VirtualAllocEx( hTargetProcess, NULL, sizeof(m_data), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( hTargetProcess, remoteData, &m_data, sizeof(m_data), NULL );
VirtualLock( remoteData, sizeof(m_data) );
// Save the address (DWORD) of remoteData to the registry, to a local file, or using setenv as suggested in other answers here

// YourDll.cpp

BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
    DataToSend m_data = {0};
    PVOID localData = /* address used in YourApp */ NULL;
    //...
    VirtualUnlock( localData, sizeof(m_data) );
    ReadProcessMemory( hProcess, localData, &m_data, sizeof(m_data), NULL );
    VirtualFree( localData, 0, MEM_RELEASE );
}
0 голосов
/ 13 марта 2012

Это «плохо» и «безобразно», но вы можете поместить аргументы в стек с помощью встроенного ASM, прежде чем сделать вызов и отбросить их обратно почти таким же образом. Очень взломанное решение, но оно может работать. Я отмечаю это только потому, что это ВОЗМОЖНО, а не потому, что это хороший способ сделать что-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...