Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« : 19-08-2005 06:06 » |
|
Вопрос немного странный.
Просто я не делал этого раньше в таком вот виде.
Есть программа, в которой есть некии функции. К ней пишется подключаемая динамически DLL-ка...
У программы есть набор своих билиотек, которые тоже подключаются в runtime
Нужно, что бы при написании DLL динамической, можно было использовать DLL программы как набор управляющих функций...
Примерно так.
Нпример у программы есть тип жанных в виде void * который создается динамически. Надо что бы в момент runtime он был сформирован и передан в DLL стороннюю как параметр определенной структуры и размера, заданный в DLL.
Таким образом я должен передать с помощью SDK и ее функции....
Но при подключении SDL DLL к DLL сторонней создается еще один instance и получается глупость...
Как это обойти.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Hooter
|
|
« Ответ #1 : 19-08-2005 09:32 » |
|
не очень понятно, если честно Есть программа, в которой есть некии функции. К ней пишется подключаемая динамически DLL-ка... У программы есть набор своих билиотек, которые тоже подключаются в runtime Нужно, что бы при написании DLL динамической, можно было использовать DLL программы как набор управляющих функций...
Если я правильно понял, то нужно передавать некие данные из программы или DLL в другую DLL, которая подключается неизвестнно когда?.. Если так, то в любой момент времени из программы или DLL можно узнать подключена ли какая-то DLL с помощью GetModuleHandle (нужно знать имя DLL). Если модуль подключен, то можно получить адрес нужной функции с помощью GetProcAddress (нужно знать имя функции), вызывать эту функцию и передавть в нее данные (нужно знать семантику функции).
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #2 : 19-08-2005 09:40 » |
|
Hooter - ты правильно понял в принципе.
Но немного не так. я хочу в DLL созаваемой не мной предоставить инетрфейс в виде готовых библиотек к работающей программе, например к серверу.
Однако вызов не должен быть по семантике, а желательно стандартное подключение...
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Hooter
|
|
« Ответ #3 : 19-08-2005 09:48 » |
|
я хочу в DLL созаваемой не мной предоставить инетрфейс в виде готовых библиотек к работающей программе, например к серверу. Однако вызов не должен быть по семантике, а желательно стандартное подключение...
Что значит стандартное подключение? Если не по семантике, тогда как? Перефразируй, плз. Ты собираешься создать набор библиотек, которыми будет пользоваться кто-то другой?
|
|
|
Записан
|
|
|
|
npak
|
|
« Ответ #4 : 19-08-2005 09:58 » |
|
Гром, может быть, ты хочешь, чтобы другое приложение линковалось с набором небольших библиотек, которые при необходимости грузились бы в память процесса автоматически?
Если это так, то тебе нужны import libraries. Например, kernel32.lib, с которой линкуются все приложения, использующие win32 API, на самом деле не содержит реального кода, только заглушки, которые при вызове функций загружают kernel32.dll и передают управление реализации в dll.
import library генерируются автоматически и складывается в output каталог проекта DLL. Import libraries поставляются в составе SDK
|
|
|
Записан
|
|
|
|
Hooter
|
|
« Ответ #5 : 19-08-2005 10:10 » |
|
Да, Гром, поясни, плз. Если тебе действительно нужна линковка с помощью import libraries, то причем здесь тогда "подключение в runtime"? У программы есть набор своих билиотек, которые тоже подключаются в runtime
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #6 : 20-08-2005 18:38 » |
|
Нет так не пойдет Давайте я подробнее нарисую....
1. Есть программа А которую пишет программист А1 2. Программа умеет подгружать к себе типовую DLL Б не в момент сборки как это происходит чаще всего, а с помощью LoadLibrary.
Вызывается набор типовых ф-ий с известными параметрами.
Для этого предусмотрен механизм инициализации с передачей указателей в программу.
3. Программист Б1 пишет типовую билиотеку дабы ее подключить.
При этом у программиста Б1 нет ни кода программы А ни связи с программистом А1.
В базовую поставку программы А входят стандартный набор библиотек динамически слинкованных с программой. Они должны осуществлять некий (неважно какой) набор функциональности для программы А и библиотеки Б
Программист Б1 должен получить стандартный h файл и lib файл, стандартно слинковать это все динамически или статически, как ему удобно.
Процедура работы такова....
При нажатии на кнопку программы А запускается нужная функция библиотеки Б которая вызовами нужными программисту Б1 запускает работу того интерфейса, который упомянут ранее.
Теперь проблема.
Если я подключаю балиотеку с помощью LoadLibrary я создаю ее экземпляр, и параллельно экземпляр билиотек которые или которая, вызваются программистом Б1. Однако эти же библиотеки уже были загружены в память при старте программы А....
Как сделать так, что бы и то и другое использовало единый экземпляр билиотек и в программе А и в приложенной библиотеке Б для нормального обмена данными и работе в единой среде. Ведь и то и то - это одна аппликация....
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Finch
Спокойный
Администратор
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
Технический
Администратор
Offline
Пол:
|
|
« Ответ #8 : 20-08-2005 19:36 » |
|
Проблема, как я ее понимаю, в том, чтобы твоя динамически подгружаемая библиотека импортировала адреса ф-ий из других библиотек, уже подгруженных главным модулем. Так?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #9 : 20-08-2005 20:07 » |
|
Второй пост - да и не только.... Я не очень понимаю. Я же гружу библиотку второй раз... и опять таки в библиотеке - думаешь и данные и все будет одинаковое ?
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #10 : 20-08-2005 20:18 » |
|
Гром ты грузиш библиотеку. Винда сначало проверяет, не загружена ли она в данном приложении. Если да, то возрашает адрес той библиотеки. Естественно все адреса функций будут на тех же местах. Посмотри 20 главу книги Рихтера "Виндовс-для проффесионалов". В ней говорится, что при повторной загрузке не выполняется вызов функции BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad) Следовательно, если в ней ты иницилизируеш переменные, то они не будут иницилизированы повторно.
|
|
« Последнее редактирование: 20-08-2005 20:37 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 20-08-2005 20:31 » |
|
Во втором: "правильно, но не так...".
Основной модуль загружает динамическую библиотеку и, когда он зывывает ее ф-ии, они находятся в его адресном пространстве. Тут и код, и данные должны быть доступны. Т.е., указатели валидны, а адреса ф-ий ты можешь получить вручную. Чего еще не хватает?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #12 : 21-08-2005 06:15 » |
|
Finch - ну не - не надо меня учить азам Суть проста, я вызываю библиотеку из библиотеки. А не два раза из одной и той же аппдикации. Кроме того ты путаешь коллчиество загруженных dll и колличество инстансов билиотеки. Если я поднял ie билиотеку то моя программа будет использовать тот же бинарник, но создаст свой экземпляр инстансов и данных, которые будут моими и значения данных ie я не увижу.... RXL - я не уверен, что подгрузка явная библиотеки не даст мне эффект второго инстанса в моем случае древовидного вызова, если кто уже делал, поделитесь данными или сделайте ксперимент у кого есть время. Мне важно точно знать, а не "по идее" , "по идее" я с вами всеми согласен.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Finch
Спокойный
Администратор
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.defLIBRARY 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++ »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
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
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #15 : 21-08-2005 15:32 » |
|
С какой радости в разных билиотеках одноименная функция принимаеит один и тот же адресс - на лице явная ошибка....
Ты можеш ткнуть пальцем где имеется один и тот же адрес двух разных функций. sq1 = 0x1000100a sq2 = 0x0035100a Это вообше то разные цифры. Или я уже не могу читать цифры? Даже если бибилиотека грузится по умолчанию. Виндовс сама вызывает функцию LoadLibrary. Дж. Рихтер "Виндовс для проффессионалов" При его запуске загрузчик операционной системы выполняет следующие операции
1. Загрузчик операционной системы создает виртуальное адресное пространство для нового процесса и проецирует па пего исполняемый модуль. 2. Далее загрузчик анализирует раздел импорта, находит все необходимые DLLмодули и тоже проецирует на адресное пространство процесса. Заметьте, что DLL может импортировать функции и переменные их другой DLL, а значит, у нее может быть собственный раздел импорта. Заканчивая подготовку процесса к работе, загрузчик просматривает раздел импорта каждого модуля и проецирует все требуемые DLL-модули на адресное пространство этого процесса. Как видите, на инициализацию процесса может уйти довольно длительное время.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #16 : 21-08-2005 16:23 » |
|
Вот примерно по твоим условиям: Первая библиотека Lib1.DllLib1.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.DefLIBRARY Lib1
DESCRIPTION 'Probe DLL'
EXPORTS SetX @1 GetX @2
Вторая библиотека Lib2Lib2.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.DefLIBRARY 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++ »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #17 : 21-08-2005 16:37 » |
|
ins1 = 0x10000000 ins2 = 0x10000000 Я это имел ввиду А вот за полный пример спасибо... Итак получаем, что в обоих случаях мы имеем одинаковые данные и один общий экземпляр библиотеки. Единственное, что я вижу, что в приведенном тобой тексте нет упоминания LoadLibrary. Насколько я помню вызов библиотеки с помощью функции LoadLibrary не одинаков для случаев когда есть h файл и когда нету его. В первом случае семантика функций известна, и имеется адреса экспортируемых функций которые проходят через нас. Во втором слчае вызов идет только по адресу который заранее при линковке неизвестен.... Я просто уже давно в винде не работал так глубоко - кое что подзабыл - ты уж прости не злись
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
npak
|
|
« Ответ #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.
|
|
|
Записан
|
|
|
|
npak
|
|
« Ответ #19 : 22-08-2005 11:04 » |
|
LoadLibrary и GetProcAddress работают одинаково как при наличии , так и при отсутствии #include "my.h" в исходниках. Эти функции работают со путями и строками и не вкладывают никакой зависящей от приложения семантики в свои действия.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #20 : 22-08-2005 11:24 » |
|
Самый прикол, что в случае работы с Load Library невозможно грузить функции описанные по стандарту С++ только С. Внутре вызывай че хошь а так не моги, так что видимо отменяется вся така байда....
Хотя соблазна велик - хотел бы динамически грузить функции с знанием структур и имен файлов.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #21 : 22-08-2005 11:47 » |
|
Гром, а кто тебе мешает сделать примерно как я. typedef int (__stdcall *TSetQuery)(void); ..................... TSetQuery sq1=GetProcAddress(lib1,"SetQuery"); int ins1=sq1();
Шаблоны всех фукнкций опредилить в заголовочном файле. А потом только останется иницилизировать переменные, как функция. И работать.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
npak
|
|
« Ответ #22 : 22-08-2005 12:29 » |
|
С++ имена грузить возможно, только надо знать, как они трансформируются (name mangling). Если не хочется связываться с name mangling, то надо пользоваться import library: при построении import library компилятор генерирует код, который знает, какое имя грузить из DLL
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #23 : 22-08-2005 12:40 » |
|
Если в проект библиотеки вставлять Def файлы. То компилятор не переворачивает имена stdcall формат.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #24 : 22-08-2005 15:25 » |
|
Есть маленький ньюанс во всем этом. Если я хочу это использовать - то я должен сделать так, что бы создателю DLL не пришлось бы думать как писать. Он должен использовать все просто - создал библиотеку отдал мне - все прогрузилось.
Вопрос такой, есть у меня только dll файл - без заголовочного и деф и либ файла. Импорт библиотеки import library идет по либ файлу. Простая подгрузка идет по заголовочному, я должен грузить простым способом. Итак Finch я попробую с stdcall скажу о результатах.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #25 : 22-08-2005 16:18 » |
|
Гром посмотри тему https://forum.shelek.ru/index.php/topic,3621.0.html . Там npak Расписал как получить .lib файл. Также можно получить имена функций. А вот с параметрами функций будут проблемы, если вообше ничего не известно о библиотеке. Но по идее говоря, если Вы разрабатываете проект вместе, то должны согласовывать интерфейс экспортируемых функций. Поэтому я думаю не должно быть проблем с .lib и .h файлами.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #26 : 22-08-2005 19:08 » |
|
Вить - неужели ты думаешь что я не умею собрать либ файл???
Ч написал условие работы причем ты знаешь какой.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Anchorite
Гость
|
|
« Ответ #27 : 22-08-2005 19:22 » |
|
Гром, ты забыл о такой вещи как COM. Для своих нужд ты можешь использовать не самого его в чистом виде, а некоторое его подобие.
|
|
|
Записан
|
|
|
|
Hooter
|
|
« Ответ #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 »
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #29 : 23-08-2005 07:25 » |
|
Я не являюсь супре-гуру, поэтому фабрику, например, никогда не использовал. Я расскажу идею, а вы подумайте. Звучит примерно так. Есть идея программы. Не вдаваясь пока (нет у меня еще полного готового описания задачи поэтому не могу поделиться) в саму ее суть, скажу что она технически должна делать.... Имеется ХХХ железо. Оно чего то там делает и имеет коммуникации. Через некий YYY интерфейс есть возможность тестировать ее готовность после произовдства или в момент разработки. Пишется программка ААА которая: а) имеет набор DLL которые закрывают собой наиболее популярные типы интерфейсов (Serial, Network, USB, LPT и т.д. б) Все они имеют верхний доступный SDK интерфейс, который не связан с типом связи. г) имеется заранее придуманная структура пакетов, которые будут служить для отправки любых данных внутрь девайса и получаться из него. Программа умеет создавать и хранить наборы тестов. Умеет их запускать и работать с их результатами. В качестве тестов иогут быть а) скрипты б) DLL на данный момент выбор типа написания самих тестов до конца не отработан, да и не выбран мной. Можеит а) может б) а скорее всего и то и другое. Для простых тестов а) для посложнее б). В варианте б) продуман следующий интерфейс. 1. Инициализирующая фунция. 2. Функции обслуживания теста для реал-тайм или как там пойдет. 3. Функции тестов с набором данных по их вызову (по нескольку типов по желанию заказчика). Внутри же может быть что угодно.... В SDK вышеупомянутом кроме функций пакетов и функций послки и приема будут функции вызова настроек передачи параметров в программу и т.д. и т.п. Т.е. структура да обозначена в общих чертах, однако расчет идет на то, что человек который купит такую программу сможет написать DLL как ему хочется только с набором нужных функций и подключить ее а) в рантайм. б) без изменения кода программы. в) сможет получить максимально удобную и простую функциональность для себя. Теперь моймите меня правильно, что окромя интерфейса внешнего программного есть проблема какой путь подключения выбрать - как его обустроить и вообще.... Пока все находится только в моей голове и проблема с библиотеками возникает именно из-за того, что а) SDK должны подключаться и в программе и в тестовых билиотеках и иметь общий экземпляр. б) Я должен уметь правильно все конигурировать из программы для каждого теста - и т.д. и т.п
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
|