Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: Dll как SDK  (Прочитано 69069 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« : 19-08-2005 06:06 » 

Вопрос немного странный.

Просто я не делал этого раньше в таком вот виде.

Есть программа, в которой есть некии функции.
К ней пишется подключаемая динамически DLL-ка...

У программы есть набор своих билиотек, которые тоже подключаются в runtime

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

Примерно так.

Нпример у программы есть тип жанных в виде void * который создается динамически. Надо что бы в момент runtime он был сформирован и передан в DLL стороннюю как параметр определенной структуры и размера, заданный в DLL.

Таким образом я должен передать с помощью SDK и ее функции....

Но при подключении SDL DLL к DLL сторонней создается еще один instance и получается глупость...


Как это обойти.
Записан

А птичку нашу прошу не обижать!!!
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 19-08-2005 09:32 » 

не очень понятно, если честно Жаль
 
Есть программа, в которой есть некии функции.
К ней пишется подключаемая динамически DLL-ка...
У программы есть набор своих билиотек, которые тоже подключаются в runtime
Нужно, что бы при написании DLL динамической, можно было использовать DLL программы как набор управляющих функций...

Если я правильно понял, то нужно передавать некие данные из программы или DLL в другую DLL, которая подключается неизвестнно когда?..

Если так, то в любой момент времени из программы или DLL можно узнать подключена ли какая-то DLL с помощью GetModuleHandle (нужно знать имя DLL). Если модуль подключен, то можно получить адрес нужной функции с помощью GetProcAddress (нужно знать имя функции), вызывать эту функцию и передавть в нее данные (нужно знать семантику функции).

Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #2 : 19-08-2005 09:40 » 

Hooter - ты правильно понял в принципе.

Но немного не так.
я хочу в DLL созаваемой не мной предоставить инетрфейс в виде готовых библиотек к работающей программе, например к серверу.

Однако вызов не должен быть по семантике, а желательно стандартное подключение...
Записан

А птичку нашу прошу не обижать!!!
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 19-08-2005 09:48 » 

я хочу в DLL созаваемой не мной предоставить инетрфейс в виде готовых библиотек к работающей программе, например к серверу.
Однако вызов не должен быть по семантике, а желательно стандартное подключение...
Что значит стандартное подключение? Если не по семантике, тогда как? Перефразируй, плз.

Ты собираешься создать набор библиотек, которыми будет пользоваться кто-то другой?
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 19-08-2005 09:58 » 

Гром, может быть, ты хочешь, чтобы другое приложение линковалось с набором небольших библиотек, которые при необходимости грузились бы в память процесса автоматически?

Если это так, то тебе нужны import libraries.  Например, kernel32.lib, с которой линкуются все приложения, использующие win32 API, на самом деле не содержит реального кода, только заглушки, которые при вызове функций загружают kernel32.dll и передают управление реализации в dll.

import library генерируются автоматически и складывается в output каталог проекта DLL.  Import libraries поставляются в составе SDK
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 19-08-2005 10:10 » 

Да, Гром, поясни, плз.
Если тебе действительно нужна линковка с помощью import libraries, то причем здесь тогда "подключение в runtime"?
У программы есть набор своих билиотек, которые тоже подключаются в runtime
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #6 : 20-08-2005 18:38 » 

Нет так не пойдет
Давайте я подробнее нарисую....

1. Есть программа А которую пишет программист А1
2. Программа умеет подгружать к себе типовую DLL Б не в момент сборки как это происходит чаще всего, а с помощью LoadLibrary.

Вызывается набор типовых ф-ий с известными параметрами.

Для этого предусмотрен механизм инициализации с передачей указателей в программу.

3. Программист Б1 пишет типовую билиотеку дабы ее подключить.

При этом у программиста Б1 нет ни кода программы А ни связи с программистом А1.

В базовую поставку программы А входят стандартный набор библиотек динамически слинкованных с программой. Они должны осуществлять некий (неважно какой) набор функциональности для программы А и библиотеки Б

Программист Б1 должен получить стандартный h файл и lib файл, стандартно слинковать это все динамически или статически, как ему удобно.


Процедура работы такова....

При нажатии на кнопку программы А запускается нужная функция библиотеки Б которая вызовами нужными программисту Б1 запускает работу того интерфейса, который упомянут ранее.

Теперь проблема.

Если я подключаю балиотеку с помощью LoadLibrary я создаю ее экземпляр, и параллельно экземпляр билиотек которые или которая, вызваются программистом Б1.
Однако эти же библиотеки уже были загружены в память при старте программы А....

Как сделать так, что бы и то и другое использовало единый экземпляр билиотек и в программе А и в приложенной библиотеке Б для нормального обмена данными и работе в единой среде. Ведь и то и то - это одна аппликация....

Записан

А птичку нашу прошу не обижать!!!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #7 : 20-08-2005 18:55 » 

Гром, честно говоря не совсем допонял.
Винда сама регулирует, чтобы библиотека загружалась в единственном экземпляре. На все приложения, которые ее используют. Можеш попробывать. В одном и том приложении вызвать загрузку дважды одной и той же библиотеки. Тебе придет один и тот же hInstance библиотеки.

Код:
#include <windows.h>
int main()
{
HINSTANCE lib1=LoadLibrary("KPAPI32.DLL");
HINSTANCE lib2=LoadLibrary("KPAPI32.DLL");
return 0;
}
У меня после выполнения lib1 и lib2 равны 0x10000000

Если ты используеш библиотеку в двух разных приложениях, тогда надо просто согласовать адреса загрузки всех библиотек используемых в приложениях.
« Последнее редактирование: 20-08-2005 19:06 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 20-08-2005 19:36 » 

Проблема, как я ее понимаю, в том, чтобы твоя динамически подгружаемая библиотека импортировала адреса ф-ий из других библиотек, уже подгруженных главным модулем. Так?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #9 : 20-08-2005 20:07 » 

Второй пост - да и не только....
Я не очень понимаю. Я же гружу библиотку второй раз... и опять таки в библиотеке - думаешь и данные и все будет одинаковое ?

Записан

А птичку нашу прошу не обижать!!!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #10 : 20-08-2005 20:18 » 

Гром ты грузиш библиотеку. Винда сначало проверяет, не загружена ли она в данном приложении. Если да, то возрашает адрес той библиотеки. Естественно все адреса функций будут на тех же местах. 
Посмотри 20 главу книги Рихтера "Виндовс-для проффесионалов". В ней говорится, что при повторной загрузке не выполняется вызов функции BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad)
Следовательно, если в ней ты иницилизируеш переменные, то они не будут иницилизированы повторно.
« Последнее редактирование: 20-08-2005 20:37 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 20-08-2005 20:31 » 

Во втором: "правильно, но не так...".

Основной модуль загружает динамическую библиотеку и, когда он зывывает ее ф-ии, они находятся в его адресном пространстве. Тут и код, и данные должны быть доступны. Т.е., указатели валидны, а адреса ф-ий ты можешь получить вручную. Чего еще не хватает?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #12 : 21-08-2005 06:15 » 

Finch - ну не - не надо меня учить азам Улыбаюсь

Суть проста, я вызываю библиотеку из библиотеки. А не два раза из одной и той же аппдикации.
Кроме того ты путаешь коллчиество загруженных dll и колличество инстансов билиотеки.

Если я поднял ie билиотеку то моя программа будет использовать тот же бинарник, но создаст свой экземпляр инстансов и данных, которые будут моими и значения данных ie я не увижу....

RXL - я не уверен, что подгрузка явная библиотеки не даст мне эффект второго инстанса в моем случае древовидного вызова, если кто уже делал, поделитесь данными или сделайте ксперимент у кого есть время.
Мне важно точно знать, а не "по идее" , "по идее" я с вами всеми согласен.
Записан

А птичку нашу прошу не обижать!!!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #13 : 21-08-2005 14:00 » 

Быстрый пример:

Первая библиотека Lib1
Lib1.h
Код:
#ifndef DLLLOADAPI
#define DLLLOADAPI extern "C" __declspec(dllimport)
#endif

//-------------------------------------------------------------------
DLLLOADAPI  int __stdcall SetQuery(void);

//-------------------------------------------------------------------

Lib1.cpp
Код:
#include <windows.h>

#define DLLLOADAPI extern "C" __declspec(dllexport)
#include "Lib1.h"


HINSTANCE hinstan;

//-------------------------------------------------------------------
int  __stdcall SetQuery(void)
{
return (int) hinstan;
}

BOOL WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void*)
{

switch( reason )
   {
case DLL_PROCESS_ATTACH:
  hinstan=hinst;
           // Initialize once for each new process.
           // Return FALSE to fail DLL load.
           break;

      case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

      case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

      case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

Вторая Библиотека Lib2
Lib2.h
Код:
#ifndef DLLLOADAPI
#define DLLLOADAPI extern "C" __declspec(dllimport)
#endif

//-------------------------------------------------------------------
DLLLOADAPI  int __stdcall SetQuery(void);

//-------------------------------------------------------------------

Lib2.cpp
Код:
#include <windows.h>

#define DLLLOADAPI extern "C" __declspec(dllexport)
#include "Lib2.h"


HINSTANCE hinstan;

//-------------------------------------------------------------------
int  __stdcall SetQuery(void)
{
return (int) hinstan;
}

BOOL WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void*)
{

switch( reason )
   {
case DLL_PROCESS_ATTACH:
  hinstan=LoadLibrary("Lib1.Dll");
           // Initialize once for each new process.
           // Return FALSE to fail DLL load.
           break;

      case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

      case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

      case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}


Обший Def Файл
Library.def
Код:
LIBRARY     Library                       

DESCRIPTION 'Probe DLL'

EXPORTS
            SetQuery                      @1

Ну сам исполняемый модуль
Main.cpp
Код:
#include <windows.h>
typedef int  (__stdcall *TSetQuery)(void);
int main()
{

HINSTANCE lib1=LoadLibrary("Lib1.dll");
TSetQuery sq1=GetProcAddress(lib1,"SetQuery");
int ins1=sq1();
HINSTANCE lib2=LoadLibrary("Lib2.dll");
TSetQuery sq2=GetProcAddress(lib2,"SetQuery");
int ins2=sq2();
        return 0;
}

После исполнения переменные принимают значения:
lib1  = 0x10000000
sq1  = 0x1000100a
ins1 = 0x10000000
lib2  = 0x00350000
sq2  = 0x0035100a
ins2 = 0x10000000
« Последнее редактирование: 20-12-2007 16:11 от Алексей1153++ » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #14 : 21-08-2005 15:12 » 

Давай проще...
1. lib1.dll должна иметь функции

Send ()
{
    SendData (x);
}

SendX( int _x)
{
    x = _x;
}




lib2.dll должна иметь функцию
Run()
{

SendX(10);

}



Во второй билиотеке есть вызов


#include "lib1.h"
 и никаких LoadLibrary полное явное подгружение через lib1.lib .

В программе идет так


#include "lib1.h"

typedef void (void) /* указатель на фукцию типа Run() из lib2 полностью не пишу - время нет */

main()
{
hInstance = LoadLibrary(Lib2);

/* Вызов функции Run() с помощью поинтера */

Send();

}


Должна быть отослана цифра 10.



Разница с твоим описанием в том, что я подгружаю программой и первую и вторую билиотеку. Первую с помощью обычного метода в момент линковки - вторую динамически через loadLibrary.

А сама библиотека тоже должна во время линковки подгрузить себе первую. А вот потом, потом из программы будет вызвана функция второй библиотеки в которой та с помощью вызова функций первой установит в памяти нужные значения и потом программа сделает нужный посыл, нужных данных в нужном направлении....


Идея такая поставлять программу с SDK с помощью которого будет писаться некий кит под себя для среды в котором с помощью SDK будет написаны нужные функции....

Вот так вот.
А так как ты пишешь вообще непонятно.
С какой радости в разных билиотеках одноименная функция принимаеит один и тот же адресс - на лице явная ошибка....
Или я чего то не понял....




Записан

А птичку нашу прошу не обижать!!!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #15 : 21-08-2005 15:32 » 

Цитата
С какой радости в разных билиотеках одноименная функция принимаеит один и тот же адресс - на лице явная ошибка....
Ты можеш ткнуть пальцем где имеется один и тот же адрес двух разных функций.
sq1  = 0x1000100a
sq2  = 0x0035100a
Это вообше то разные цифры. Или я уже не могу читать цифры?
Даже если бибилиотека грузится по умолчанию. Виндовс сама вызывает функцию LoadLibrary. Дж. Рихтер "Виндовс для проффессионалов"
Цитата
При его запуске загрузчик операционной системы выполняет следующие операции

1. Загрузчик операционной системы создает виртуальное адресное пространство для нового процесса и проецирует па пего исполняемый модуль.
2. Далее загрузчик анализирует раздел импорта, находит все необходимые DLLмодули и тоже проецирует на адресное пространство процесса. Заметьте, что DLL может импортировать функции и переменные их другой DLL, а значит, у нее может быть собственный раздел импорта. Заканчивая подготовку процесса к работе, загрузчик просматривает раздел импорта каждого модуля и проецирует все требуемые DLL-модули на адресное пространство этого процесса. Как видите, на инициализацию процесса может уйти довольно длительное время.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #16 : 21-08-2005 16:23 » 

Вот примерно по твоим условиям:

Первая библиотека Lib1.Dll
Lib1.h
Код:
#ifndef DLLLOADAPI
#define DLLLOADAPI extern "C" __declspec(dllimport)
#endif

//-------------------------------------------------------------------
DLLLOADAPI  int __stdcall GetX(void);
DLLLOADAPI  void  __stdcall SetX(int _x);
//-------------------------------------------------------------------

Lib1.cpp
Код:
#include <windows.h>

#define DLLLOADAPI extern "C" __declspec(dllexport)
#include "Lib1.h"


int x;

//-------------------------------------------------------------------
void  __stdcall SetX(int _x)
{
x=_x;
}

int __stdcall GetX(void)
{
return x;
}

BOOL WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void*)
{

switch( reason )
   {
case DLL_PROCESS_ATTACH:
x=0;
           // Initialize once for each new process.
           // Return FALSE to fail DLL load.
           break;

      case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

      case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

      case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

Lib1.Def
Код:
LIBRARY     Lib1                       

DESCRIPTION 'Probe DLL'

EXPORTS
    SetX                      @1
    GetX                      @2

Вторая библиотека Lib2

Lib2.h
Код:
#ifndef DLLLOADAPI
#define DLLLOADAPI extern "C" __declspec(dllimport)
#endif

//-------------------------------------------------------------------
DLLLOADAPI  void  __stdcall SetX(int _x);

//-------------------------------------------------------------------

Lib2.cpp
Код:
#include <windows.h>

#define DLLLOADAPI extern "C" __declspec(dllexport)
#include "Lib2.h"

typedef void  (__stdcall *TSetX)(int _x);

HINSTANCE lib1;
TSetX sx;

//-------------------------------------------------------------------
void  __stdcall SetX(int _x)
{
sx(_x);
}

BOOL WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void*)
{

switch( reason )
   {
case DLL_PROCESS_ATTACH:
  lib1=LoadLibrary("Lib1.Dll");
  sx=(TSetX ) GetProcAddress(lib1,"SetX");
  sx(10);

           // Initialize once for each new process.
           // Return FALSE to fail DLL load.
           break;

      case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

      case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

      case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

Lib2.Def
Код:
LIBRARY     Lib2                       

DESCRIPTION 'Probe DLL'

EXPORTS
            SetX                      @1

Ну и сам исполняемый файл

Main.cpp
Код:
#include <windows.h>
#include "Lib1.h"

int main()
{
int x=GetX();
HINSTANCE lib2=LoadLibrary("Lib2.dll");
x=GetX();

return 0;
}

До загрузки Lib2.dll     x = 0
После загрузки lib2.dll x = 10
« Последнее редактирование: 20-12-2007 16:13 от Алексей1153++ » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #17 : 21-08-2005 16:37 » 

ins1 = 0x10000000
ins2 = 0x10000000

Я это имел ввиду Улыбаюсь

А вот за полный пример спасибо...
Итак получаем, что в обоих случаях мы имеем одинаковые данные и один общий экземпляр библиотеки.

Единственное, что я вижу, что в приведенном тобой тексте нет упоминания LoadLibrary.

Насколько я помню вызов библиотеки с помощью функции LoadLibrary не одинаков для случаев когда есть h файл и когда нету его.

В первом случае семантика функций известна, и имеется адреса экспортируемых функций которые проходят через нас. Во втором слчае вызов идет только по адресу который заранее при линковке неизвестен....

Я просто уже давно в винде не работал так глубоко - кое что подзабыл - ты уж прости не злись Улыбаюсь
Записан

А птичку нашу прошу не обижать!!!
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 22-08-2005 10:58 » 

Если под "библиотекой" подразумевается DLL, то при соблюдении некоторых предосторожностей в адресное просторанство процесса действительно отображается только один экземпляр DLL и создаётся один экземпляр данных.  Главное, что надо соблюдать -- чтобы DLL грузились из одного файла.  Если при разных вызовах LoadLibrary будут найдены разные файлы, то загружены будут разные DLL с одним именем.  Например,

Код:
#include <windows.h>
#include <stdio.h>

#define PATH1 "msvcrt40"
#define PATH2 "c:\\WINNT\\ServicePackFiles\\i386\\msvcrt40.dll"

int main(int argc, char * argv[])
{
    HMODULE hmod2;
    HMODULE hmod1 = LoadLibrary(PATH1);
    if (hmod1 == NULL)
    {
        printf("Failed to load module %s, error %d\n", PATH1, GetLastError());
        return 1;
    }
    printf("Loaded module %s\n", PATH1);

    hmod2 = LoadLibrary(PATH2);
    if (hmod2 == NULL)
    {
        printf("Failed to load module %s, error %d\n", PATH2, GetLastError());
        return 1;
    }
    printf("Loaded module %s\n", PATH2);

    return 0;
}

В первом LoadLibrary будет загружен модуль из c:\winnt\system32\msvcrt40.dll, во втором случае будет загружен модуль из c:\WINNT\ServicePackFiles\i386\msvcrt40.dll.  Системе наплевать, что эти два модуля побитово совпадают, раз они найдены в разных местах, то определяются как разные и, соответственно, оба загружаются.

Для того, чтобы избежать подобной проблемы, надо использовать одну и ту же строку при загрузке библиотеки.  Один из способов обеспечить это -- не вызывать LoadLibrary самостоятельно, а пользоваться import library, .lib файлом, который автоматически генерируется компилятором при сборке DLL.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 22-08-2005 11:04 » 

LoadLibrary и GetProcAddress работают одинаково как при наличии  , так и при отсутствии #include "my.h" в исходниках.  Эти функции работают со путями и строками и не вкладывают никакой зависящей от приложения семантики в свои действия. 
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #20 : 22-08-2005 11:24 » 

Самый прикол, что в случае работы с Load Library невозможно грузить функции описанные по стандарту С++ только С. Внутре вызывай че хошь а так не моги, так что видимо отменяется вся така байда....

Хотя соблазна велик - хотел бы динамически грузить функции с знанием структур и имен файлов.
Записан

А птичку нашу прошу не обижать!!!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #21 : 22-08-2005 11:47 » 

Гром, а кто тебе мешает сделать примерно как я.
Код:
typedef int  (__stdcall *TSetQuery)(void);
.....................
TSetQuery sq1=GetProcAddress(lib1,"SetQuery");
int ins1=sq1();

Шаблоны всех фукнкций опредилить в заголовочном файле. А потом только останется иницилизировать переменные, как функция. И работать.

Записан

Не будите спашяго дракона.
             Джаффар (Коша)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 22-08-2005 12:29 » 

С++ имена грузить возможно, только надо знать, как они трансформируются (name mangling).
Если не хочется связываться с name mangling, то надо пользоваться import library: при построении import library компилятор генерирует код, который знает, какое имя грузить из DLL
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #23 : 22-08-2005 12:40 » 

Если в проект библиотеки вставлять Def файлы. То компилятор не переворачивает имена stdcall формат.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #24 : 22-08-2005 15:25 » 

Есть маленький ньюанс во всем этом.
Если я хочу это использовать - то я должен сделать так, что бы создателю DLL не пришлось бы думать как писать. Он должен использовать все просто - создал библиотеку отдал мне - все прогрузилось.


Вопрос такой, есть у меня только dll файл - без заголовочного и деф и либ файла.
Импорт библиотеки import library идет по либ файлу. Простая подгрузка идет по заголовочному, я должен грузить простым способом.
Итак Finch я попробую с stdcall скажу о результатах.
Записан

А птичку нашу прошу не обижать!!!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #25 : 22-08-2005 16:18 » 

Гром посмотри тему https://forum.shelek.ru/index.php/topic,3621.0.html . Там npak Расписал как получить .lib  файл. Также можно получить имена функций. А вот с параметрами функций будут проблемы, если вообше ничего не известно о библиотеке.
Но по идее говоря, если Вы разрабатываете проект вместе, то должны согласовывать интерфейс экспортируемых функций. Поэтому я думаю не должно быть проблем с .lib и .h файлами.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #26 : 22-08-2005 19:08 » 

Вить - неужели ты думаешь что я не умею собрать либ файл???

Ч написал условие работы причем ты знаешь какой.
Записан

А птичку нашу прошу не обижать!!!
Anchorite
Гость
« Ответ #27 : 22-08-2005 19:22 » 

Гром, ты забыл о такой вещи как COM. Для своих нужд ты можешь использовать не самого его в чистом виде, а некоторое его подобие.
Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 23-08-2005 05:21 » 

Самый прикол, что в случае работы с Load Library невозможно грузить функции описанные по стандарту С++ только С. Внутре вызывай че хошь а так не моги, так что видимо отменяется вся така байда....

Хотя соблазна велик - хотел бы динамически грузить функции с знанием структур и имен файлов.

Для создания экземпляров классов можно использовать такой механизм, как фабрика. То есть функция,  возвращающая ссылку или указатель на созданный внутри библиотеки класс.

Есть маленький ньюанс во всем этом.
Если я хочу это использовать - то я должен сделать так, что бы создателю DLL не пришлось бы думать как писать. Он должен использовать все просто - создал библиотеку отдал мне - все прогрузилось.

В любом случае, нужен хотя бы минимальный (заранее оговоренный разработчиками) интерфейс взаимодейстия между модулями.

Если будешь использовать фабрику классов, то необходим еще и минимальный интерфейс взаимодействия с экземпляром класса. Можно, по принципу, как это сделано в COM.

Первый модуль.
Код:
class CMyInterface
{
    virtual int some_action () = 0;
}

class CMyClass : public CMyInterface
{
    int some_action ();
    void implementation_func1 ();
    void implementation_func2 ();
}

void * exported createMyClass ()
{
    return new CMyClass;
}

Слово exported использовано для того, чтобы показать, что функция является экспортируемой из модуля.

Второй модуль:
Код:
class CMyInterface
{
    virtual int some_action () = 0;
}

void some_func ()
{
    ...
    createMyClass = ::GetProcAddress (module, "createMyClass");
    ...
    void *instance = createMyClass ();
    CMyInterface *obj = (CMyInterface *)instance;
     int res = obj->some_action ();
}

Здесь интерфейс CMyInterface - является заранее оговоренным интерфейсом взаимодействия с экземпляром класса,
а экспортируемая функция createMyClass - заранее оговоренный интерфейс взаимодействия с модулем (библиотекой).

PS  Гром, я прошу прощения, если это для тебя - прописные истины. Мне просто до сих пор не совсем ясно, как ты себе представляешь себе взаимодействие с чужой библиотекой, если "создателю DLL не пришлось бы думать как писать".
« Последнее редактирование: 23-08-2005 05:37 от Hooter » Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #29 : 23-08-2005 07:25 » 

Я не являюсь супре-гуру, Улыбаюсь поэтому фабрику, например, никогда не использовал.

Я расскажу идею, а вы подумайте.

Звучит примерно так.
Есть идея программы. Не вдаваясь пока (нет у меня еще полного готового описания задачи поэтому не могу поделиться) в саму ее суть, скажу что она технически должна делать....


Имеется ХХХ железо. Оно чего то там делает и имеет коммуникации.

Через некий YYY интерфейс есть возможность тестировать ее готовность после произовдства или в момент разработки.

Пишется программка ААА которая:

а) имеет набор DLL которые закрывают собой наиболее популярные типы интерфейсов (Serial, Network, USB, LPT и т.д.
б) Все они имеют верхний доступный SDK интерфейс, который не связан с типом связи.
г) имеется заранее придуманная структура пакетов, которые будут служить для отправки любых данных внутрь девайса и получаться из него.

Программа умеет создавать и хранить наборы тестов. Умеет их запускать и работать с их результатами.

В качестве тестов иогут быть
а) скрипты
б) DLL

на данный момент выбор типа написания самих тестов до конца не отработан, да и не выбран мной. Можеит а) может б) а скорее всего и то и другое.
Для простых тестов а) для посложнее б).

В варианте б) продуман следующий интерфейс.

1. Инициализирующая фунция.
2. Функции обслуживания теста для реал-тайм или как там пойдет.
3. Функции тестов с набором данных по их вызову (по нескольку типов по желанию заказчика).

Внутри же может быть что угодно....

В SDK вышеупомянутом кроме функций пакетов и функций послки и приема будут функции вызова настроек передачи параметров в программу и т.д. и т.п.


Т.е. структура да обозначена в общих чертах, однако расчет идет на то, что человек который купит такую программу сможет написать DLL как ему хочется только с набором нужных функций и подключить ее
а) в рантайм.
б) без изменения кода программы.
в) сможет получить максимально удобную и простую функциональность для себя.

Теперь моймите меня правильно, что окромя интерфейса внешнего программного есть проблема какой путь подключения выбрать - как его обустроить и вообще....

Пока все находится только в моей голове и проблема с библиотеками возникает именно из-за того, что
а) SDK должны подключаться и в программе и в тестовых билиотеках и иметь общий экземпляр.
б) Я должен уметь правильно все конигурировать из программы для каждого теста - и т.д. и т.п



Записан

А птичку нашу прошу не обижать!!!
Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines