1 | |
Подключить библиотеку dll01.03.2017, 09:35. Показов 8046. Ответов 166
Метки нет (Все метки)
Данным диалектом Бейсика не пользуясь, но иногда здесь бываю. Решил немного поучаствовать. Собственно вопрос в следующем: можно ли пользоватся сторонними библиотеками в этом диалекте, насколько сложен процесс использования? Цель - есть своя xll для VBA, можно убрать обертку будет dll, выложу здесь для тех кто много считает, большими числами) (Гугл не спрашивал ибо важно понять, есть целесообразность в данном продукте?)
0
|
01.03.2017, 09:35 | |
Ответы с готовыми решениями:
166
Не получается подключить библиотеку Unmanaged.dll (Firefox nss3.dll) Подключить библиотеку dll Как подключить dll библиотеку? Как подключить .dll библиотеку? |
01.04.2018, 00:10 | 61 |
Слов то таких не знаю, да и не особо хочется если честно)))
Это печально. Да и в принципе не сильно он нужен. Мож до пенсии и разгребу))) Сложность в том, что не использую 4GL вовсе. А чтобы чем-то реально пользоваться со знанием, а не тыкать пальцем - нужно изучить. Т.е. осознавать, что реально происходит с данными в памяти. Чтобы изучить этот самый COM, помню, люди говорили надо прочитать и понять стопку толстых книг, что для меня не один год. Т.е. делать это ради того, чтобы протестировать чью-то программу - занятие нецелесообразное. Просто так лезть не понимая сути вопроса - это ну совсем бичарство, так не делаю. Просто не могу понять зачем всё это вообще нужно. В чём профит простыми словами? Т.е. чтобы открыть этот драный COM нужно переписать тот исходник Анатолия на FB. А чтобы его переписать нужно понять, что он делает, что делает каждая его функция, это время, т.е. дофига времени. Посмотрю на досуге. Но правда толку, у bedvit-a же 64 битная библа.
0
|
01.04.2018, 10:26 [ТС] | 62 |
Не думал что так сильно отличаются диалекты Basic. В VBA - подключение элементарно одной строкой CreateObject("имя библиотеки") . как по мне куча толстых книг нужна разработчику (да и это в случае если с нуля делать все руками, что редкость), клиенту только знать как подключить.
Профит если совсем просто в том, что можно реализовать ООП в dll, на разных языках и для разных языков, т.е. передать класс/объект между языками/компиляторами. А это в свою очередь нужно, т.к. есть структуры(классы), которые нельзя привести к стандартным типам, которые можно было бы передать через win api функции или процедурные dll (моё узкое мнение, специалисты поправят, если где нужно).
0
|
locm
|
01.04.2018, 12:20
#63
|
0
|
01.04.2018, 14:07 | 64 |
Это не редкость, это становится суровой необходимостью, потому что уровень халатности
непреклонно растёт, к сожалению. И мы, старые вояки кодеры, начинаем себя даже комфортнее чувствовать. Не про это речь веду, разумеется нужна. Нужно просто знать ради чего что-то делаешь, вот вы к примеру знаете для чего и для кого вы пишете? Судя по постам знаете, но тогда если мало или нет тестеров то нужна подача какая-то более грамотная, например видео по использованию, посты на форумах и т.п. Это говорю к тому, что у меня, например, своей литературы и исходников столько, что до конца жизни разгребать, особенно когда ещё голова забита другими вещами. Анатолий(the trick) прекрасно понимает что это за область, но он, конечно, более прошаренный и талантливый во всех смыслах, мне до его уровня пердеть и пердеть. Да в FB уже много чего наворотили, просто этим не пользуюсь, расшерстил и хожу по протоптанной дорожке.
0
|
Модератор
|
||||||
01.04.2018, 21:03 | 65 | |||||
Просто ты не писал многопоточное приложение работающее с COM объектами.
Что печально? VST2 тоже объектно-ориентированный. Так со всем. Если ты разработчик, а если ты просто клиент то это не нужно. Потому что это намного удобнее. Пользователь работает с объектами которые могут быть в разных процессах, машинах единообразно. Не нужно. Тот исходник помимо работы с COM предоставляет возможность работы с ActiveX. Толк есть, насколько я помню COM объект может использоваться независимо от разрядности. Неверно. В API функцию можно передать все что угодно. Разницы нет метод объекта или API функция. В первом случае мы имеем указатель на таблицу функций, во втором указатель получаем через GetProcAddress (ну или в импорте). Под "капотом" CreateObject это просто пара вызовов API функций CLSIDFromProgID и CoCreateInstance. Quiet Snow, Очень-очень грубо. Вот к примеру если ты хочешь использовать какую-либо функцию из DLL, то ты вызываешь LoadLibrary и GetProcAddress. Также ты можешь к примеру добавить функцию в импорт, что по сути тоже самое только адреса предоставит сама система. Это ясно. В COM ты получаешь не адрес функции, а адрес на таблицу функций. Эта таблица функций называется интерфейсом. К примеру любой COM объект обязан реализовывать интерфейс IUnknown. Т.е. если ты создаешь какой-либо объект и запрашиваешь у него этот интерфейс то ты гарантировано получишь указатель на указатель на 3 функции: QueryInterface; AddRef; Release. Любой другой интерфейс должен наследоваться от IUnknown, это обозначает что любой интерфейс первыми тремя функциями содержит эти функции (QI, A, R). Запрос интерфейса осуществляется вызовом QueryInterface. К примеру ты разрабатываешь какую-либо DAW и хочешь реализовать к ней плагины. Ты разрабатываешь интерфейc ISoundProcess который содержит 3 метода: SetSampleRate; - установить частоту дискретизации. SetVolume; - установить громкость. Process; - обработать/сгенерировать звук, в зависимости от типа. Все, Теперь любой разработчик может создать COM DLL в которой будует объект/объекты реализующие этот интерфейс. Твой хост просто запрашивает этот интерфейс и получает указатели на функции которые уже индивидуальны для каждого плагина/объекта. Таблица всегда одинакова, а функции разные. Один плагин к примеру будет на Process генерировать пилу, а другой добалять Хорус. Это удобно. В хосте ты просто пишешь вроде того:
Далее к примеру ты опционально хочешь добавить возможность реализации GUI для плагина. Создаешь еще один интерфейс IGUIPlugin, в котором описываешь методы типа SetHwnd и т.д. И любой COM объект из Dll может поддерживать этот интерфейс. Удобно? Да конечно можно сделать как говорит locm, вместо одной функции просто экспортировать каждый метод по отдельности и вызывать его, передавая каждый раз указатель на объект идентифицирующий плагин/эффект. Но если к примеру ты захочешь сделать более отказоустойчивую систему, то ты можешь COM объект загрузить в другой процесс. Или к примеру твое приложение 64 битное а Dll 32 битная, ты просто используешь COM surrogate (dllhost.exe). Но фишка в том что от тебя почти ничего не требуется, в хосте как был код так и остался (к примеру посмотри работу с Excel/Word из VB6 там объект живет в другом процессе, а работаешь ты с ним точно также как с любым другим). Всю работу по синхронизации, транспортировке данных между процессами берет на себя Windows. Попробуй теперь так с экспортом функций сделать? Второй момент, если твоя DLL работает в многопоточном приложении и ты опрашиваешь объект из разных потоков то становится критичной проблема синхронизации. В STA каждый объект изолирован и всю работу по синхронизации выполняет Windows. Ты также просто вызываешь метод объекта, Windows транспортирует данные между потоками, ждет обработки и возвращает результат, тебе не нужно думать о синхронизации и т.п. ты просто вызываешь метод (функцию по указателю). COM объект работает в том потоке в котором был порожден и никаких проблем с синхронизацией не возникает. Удобно? Попробуй сделать тоже самое с экспортом функций. Фишка в том что от разработчика эти действия не требуются это реализуется все Windows.
2
|
01.04.2018, 22:42 [ТС] | 66 |
всегда уважал таких специалистов, хотя и сам не молод-то уже.
- просто тематика продукта не всем интересна, а так в блоге все описал, оформил графически, и сделал справку по интерфейсам COM (IDispatch). При наличии интереса, могу и видео по использованию добавить и оформить подробнее. The trick, хороший пост, плюсую вам. Опыта мало, в эту тему только погружаюсь, не могу понять эту информацию. Как через API передать объект, запустить конструктор, деструктор (NEW, DELETE) для него, работать на совместимых типах данных между языками без com - интерфейса с Automation-совместимыми типами данных? Все заворачивать в отдельную функцию и передавать посредством "EXPORTS" и "_stdcall", а в VBA смотреть через Declare? Выходит 50 "Declare", вместо одного CreateObject? Можно прямо на пальцах (если вас не затруднит), можно терминами VB, можно С, любыми другими (по вышепоказанным вами функциям, честно пытался усвоить инфо, видимо пока борода не выросла, не понимаю, что там бородатые дядьки запилили).
0
|
Модератор
|
||||||
01.04.2018, 23:11 | 67 | |||||
Ну вызов API функции ничем не отличается от вызова метода объекта. Если в метод можно передать все что угодно, то и в API функцию тоже, т.к. это та же самая функция.
Не понимаю. Объект можно передать в API или возвратить его из API, "через API" - что имеется в виду? COM не поддерживает конструкторы. Если нужно инициализировать объект то запрашивается один из интерфейсов IPersist и далее через Load загружается состояние. Так не делают, это просто лишнее. Зачем городить эти костыли с импортом? Чтобы потом люди ломали голову если что-то где-то не так задекларировано или вместо ссылки на объект передали что-то другое и получили вылет. Есть интерфейс - он неизменен и больше ничего не нужно. Что именно? Ну к примеру на VB6 можно же создать функцию в модуле принимающую объект?
0
|
Quiet Snow
|
01.04.2018, 23:35
#68
|
Не по теме: Анатолий, это всё очень сложно для моих старых мозгов. С нахрапу не въеду. Уже не кодил Сам ещё даже твой пример не раскурил по первой версии, тот что на ассемблере. На мой взгляд единственный дельный мануал по теме(ну кроме других твоих манов по звуку, там тоже всё кошерно), в других же источниках - одни бичи дешёвые и безалаберные :D .
0
|
02.04.2018, 00:47 [ТС] | 69 |
The trick, благодарю за ответы. Попытаюсь понять ваши и пояснить свои мысли.
Используя new мы можем создать несколько объектов одного и того же класса, со своими значениями свойств и методами, как этого достичь в процедурной dll? Про какой интерфейс вы упоминаете, в случае передачи объекта через api в процедурной dll без использования СОМ. Как без СОМ передать объект из процедурной dll, пусть из VB6(вам он ближе?) в VBA. Если все же СОМ нужен, то передавая через api в функции этот объект, как vba знает про его интерфейс, регистрация в реестре, манифест? Как его можно использовать? Пока не пойму.
0
|
Модератор
|
||||||
02.04.2018, 10:05 | 70 | |||||
Объявляется функция с параметрами инициализации, в которой создается уже объект через (new, я так понимаю C++) и возвращается из функции.
Да любой. COM объект это просто указатель, можно передавать вообще любой указатель а в функции разруливать его. К примеру в Windows есть понятие хендла. Вот он однозначно идентифицирует объект, так и тут. Но самое простое это просто передавать COM объект, если кто-то по непонятной причине боится работать с COM объектом у себя в приложении, то просто вызывая функцию из DLL передавая туда этот объект - самому вызывать метод. Такая функция для вызова метода, или даже функция для вызова функции Что имеется в виду без COM? COM объект это просто указатель, в чем проблема передать указатель? Из VB6 dll я бы просто возвращал COM объект из процедурной DLL. По типу:
Вот пример где ActiveX Dll работает без какой либо регистрации используя манифест (статью можно не читать, т.к. статья совершенно о другом). Чтобы использовать его динамически (т.е.) как в случае VBA нужно использовать контекст активации, ссылку на Reg-Free я скинул выше там все подробно описано. Там прописывается местоположение библиотеки, CLSID, PROGID, ProxyStub и т.д. те же ключи реестра. Есть уже автоматизированные приложения создающие такой манифест.
0
|
Модератор
|
||||||||||||||||
02.04.2018, 12:10 | 71 | |||||||||||||||
Quiet Snow,
Вот простейший пример использования COM библиотеки из ассемблера (думаю это самый простой способ, не в машинных кодах же писать? ). Имеем простую ActiveX dll библиотеку написанную на VB6. В ней есть класс CTest:
CLSID - это идентификатор класса, IID - это идентификатор интерфейса. Любой класс обязан реализовывать какой-нибудь интерфейс. CLSID - однозначно определяет реализацию, а IID однозначно определяет "канал" взаимодействия. К примеру тут класс CTest, а интерфейс _CTest. Любой другой класс также может реализовывать интерфейс _CTest а метод ShowMsgBox может уже делать что-то другое. Теперь напишем клиент для этой dll, на ассемблере (FASM): Без деклараций и проверок на ошибок код совсем маленький:
Не сложнее LoadLibrary и GetProcAddress. Вызов метода это просто вызов функции по указателю с передачей указателя на объект в первом параметре. Все! Никаких надуманных сложностей, километровых кодов и т.п. Дополнительно имеем большое количество преимуществ о которых я писал ранее. Если нужно сделать работу без регистрации можно и правильнее создать Reg-Free манифест либо вручную вызвать DllGetClassObject как в моем примере в блоге. Манифест также очень простой:
Если угодно можно создать объект по имени (не по CLSID), как это делается в скриптовых языках или в VB/VBA (CreateObject), просто получив CLSID по имени (ProgId) через функцию CLSIDFromProgId. В манифесте просто нужно добавить атрибут progid="TestLib.CTest".
0
|
02.04.2018, 12:28 [ТС] | 72 |
Благодарю, действительно интересно. По первой части сообщения, в общем понятно. Под COM я подразумеваю интерфейсы COM. Выходит, как я писал выше, нужно 50 Declare Function, что бы работать с библиотекой (на количество свойств и методов), все верно?
Вторая часть посложнее: 1. При Reg-Free методе, в функцию должно передаваться местоположение DLL(манифеста)? (ведь в реестре нет записи) Reg-Free методе и при это только позднее связываение? (методы и свойства посмотреть нельзя). А где этот манифест лежит, вместе с библиотекой? Надо погуглить тему и вашу ссылку. .... Пока писал появилось ваше последнее сообщение, читаю.
0
|
Модератор
|
|
02.04.2018, 13:52 | 73 |
Скорее всего да, но опять-таки в чем смысл? Для чего экспортировать 50 функций если эти функции уже есть в самом указателе на объект?
Смотря где использовать. Если пишется EXE к примеру, то манифест прописывается либо в ресурсы либо в файл name.exe.manifest Если к примеру у нас не свое приложение как VBA, то просто делаем как в секции Using the Activation Context API. Ну в случае VBA, да, иначе придется подключать библиотеку в референсы, т.к. в VBA не способа объявить интерфейс без библиотеки типов (кроме конечно кастомных костылей через стандартный модуль и т.п. хаки). Свойства можно смотреть в рантайме, это не зависит от типа связывания:
1
|
02.04.2018, 14:12 [ТС] | 74 |
так в случае процедурной dll откуда будет объект? выходит функции нужны.
Про name.exe.manifest читал, но у меня просто dll (потому собственно и пошел через реестр, не смог придумать как для dll прописать манифест - чтобы без регистрации в реестре). Почитаю инфо по ссылке. Обобщая - для моей задачи подходит больше com, чем процедурная dll (с точки зрения пользователя меньше писать кода на VBA, 1С, com - поддерживающих компиляторов, но видимо не для всех языков - для них пока не понятно насколько com выигрывает). Можно попробовать пойти через манифест, ибо регистрация в реестре пугает народ (видимо). Хотя не ясно чем (можно же ведь и под пользователем регистрировать). Минусы - нет раннего связывания, медленнее скорость обмена с dll (замерял - процентов на 50%), что существенно для быстрых вычислений (для справедливости замечу, что внутри dll скорости не меняются и не зависят от раннего или позднего связывания). The trick, Вы как специалист с большим стажем разработки, что посоветуете добавить/убрать/переделать?
0
|
Модератор
|
|
02.04.2018, 14:45 | 75 |
Ну так они и есть DllGetClassObject/DllRegisterServer/DllUnregisterServer и DllCanUnloadNow. Посмотри свою DLL в любом PE вьювере.
И для скриптовых типа vba и т.д. Ну хотелось бы посмотреть на каком языке нельзя работать с COM? Ну если очень нужно то можно сделать и раннее связывание без регистрации для VBA (для других не знаю), для VB6 к примеру все будет работать на раннем связывании без всяких дополнительных усилий. Просто тут как бы проблема не в том что регистрация нужна, а в том что когда добавляется библиотека в референсы она автоматом регистрируется даже если это не нужно. Я не знаю что будет в случае если dll не зарегистрируется, может быть описания интерфейсов "подхватятся" - это нужно уже тестировать и смотреть на машине с ограниченными правами. Тогда никаких проблем с ранним связыванием не будет. Я ничего. Все и так нормально (в плане архитектуры), а функционал я не тестировал.
1
|
02.04.2018, 16:26 [ТС] | 76 |
The trick, вы меня почти убедили что COM- это не плохо, хотя какое-то неприятие этой технологии народом просматривается.
собственно DllInstall немного подпиливал, что бы по ключу "regsvr32 /n /i" пользователь регистрировался. Я имел ввиду, что если не пользоваться объектом, а функциями из процедурной dll, то нужно будет писать вместо свойств и методов объектов, столько же функций через declare (50 штук). Что как по мне, пользователю накладнее, чем одну функцию CreateObject() (VBA, 1C), другие языки наверное посложнее. Кстати насколько сложно подключить в Freebasic? (совсем не знаю этот диалект, хочу поделится с другом библиотекой) В гугле видел такую конструкцию для FreeBasic "dhCreateObject («Word.Application», NULL, @wdApp)" Нашел какой-то Disphelper (библа). Видимо можно, надо гуглить.
0
|
03.04.2018, 20:10 | 77 |
Анатолий, я не пользуюсь FASM, слабо понимаю его синтаксис.
Вижу что там манифест уходит в ресурсы(которыми я тоже не пользуюсь), Comninvoke хз чем заменить, тот адрес что в селекторе - хз откуда он его берёт. За пример спасибо, но это опять же без соотв. навыков - х**ова туча времени чтобы разобрать. Например если было бы в MASM без всяких locals, struc, cominvoke и т.п. тогда было бы примерно ясно что там в деталях происходит. FASM всё прячет очень жёстко, уже обращал на это внимание, мне крайне не импонирует этот подход, после книги Пирогова. У меня просто сейчас не все исходники под рукой и кучу всего забыто. Думаю нужно плясать от соответствующих WinAPI и понять как структуры описать, чтобы FB всё это сожрал. Помню немного работал с Disphelper по примерам, не особо вникая в то, что под капотом, хоть это и дерьмовейший подход к программированию. Это не совсем то, там заточка под офисные приложения. Лезть под капот не очень хочется, слишком дофига кода лопатить. Добавлено через 1 час 11 минут bedvit, короче попробую пошуршать всё это, если получится завести библиотеку Анатолия с FB, тогда уже будем смотреть по вашей библиотеке.
0
|
03.04.2018, 23:02 | 79 |
Ну мне он не особо понятен. У разных ассемблеров разный синтаксис.
Мне проще например понять MOV ECX, бла бла бла CALL CS:[ECX] тут сразу видно что процедура находится по смещению ECX, чем какие-то там ссылки, по указателям, куда-то там фиг знает куда. К тому же что за формат строки BSTR? Я макросы эти не рублю совсем. Также GetTypeInfoCount GetTypeInfo GetIDsOfNames Если прототипы QueryInterface, AddRef, Release я худо бедно нашёл в хедерах винды, то где мне искать эти прототипы? Я просто пытаюсь понять всё это на самом низком уровне. Частично сейчас смотрю разные исходники и бошка взрывается просто. Это ужас какой-то. Объект и Виртуальная таблица как они впамяти организованы, да хрен его знает, нигде нету информации. Хедеры все в формате си++ с кучей деректив, который тоже не рублю. Чую с нахрапу не получится, это реально надо рубить во всём этом. Добавлено через 18 минут Вопросов дофига: Без манифеста эта штука будет работать? Т.е. если уже запускалась usage.exe. Что происходит в invoke CoCreateInstance, CLSDID_CTest, 0, CLSCTX_INPROC_SERVER, IID__CTest, addr cObject Т.е. CLSDID_CTest и IID__CTest - это указатели. addr cObject - это указатель на какую структуру? cObject в памяти как организован? Мне же просто нужен указатель на функцию, чтобы мог передать ей управление. Или это всё работает по другому?
0
|
Модератор
|
|
03.04.2018, 23:04 | 80 |
https://msdn.microsoft.com/en-... s.85).aspx В посте с кодом показано описание интерфейса и видно что он наследуется от IDispatch. Эти функции - просто методы этого интерфейса. Для понимания работы COM это не нужно это относится к Automation. Просто VB6 автоматом делает все классы Automation-совместимыми. Просто вызов функции по указателю. Ты не оперируешь объектами в COM, ты оперируешь интерфейсами. Получаешь указатель на интерфейс - это указатель на таблицу функций с фиксированным форматом. https://msdn.microsoft.com/en-... s.85).aspx
0
|
03.04.2018, 23:04 | |
03.04.2018, 23:04 | |
Помогаю со студенческими работами здесь
80
Не могу подключить dll библиотеку Как подключить библиотеку 7z.dll? Как подключить библиотеку i7000.dll? Как подключить библиотеку shell32.dll ? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |