Использование ActiveX DLL в других языках.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Использование ActiveX DLL в других языках.

Сообщение Mikle » 01.06.2005 (Ср) 10:23

Собираюсь делать на VB6 ActiveX DLL - библиотеку для общего использования из разных языков программирования. В первую очередь важны C#, C++ и Delphy. Подскажите, нет ли каких-то подводных камней? Может необходимо соблюдать какие-то определенные правила? Например в C++, вроде бы, нет Property в привычном для нас виде. Так ли это?
Как лучше передавать указатель на первый элемент массива в Public процедурах, просто "m(0)"? или лучше "ByVal VarPtr(m(0))"?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Использование ActiveX DLL в других языках.

Сообщение tyomitch » 01.06.2005 (Ср) 11:14

Mikle писал(а):Как лучше передавать указатель на первый элемент массива в Public процедурах, просто "m(0)"? или лучше "ByVal VarPtr(m(0))"?

Для простых массивов (если UDT, то выравненный и без строк) разницы нет вообще. Для сложных - выбирай в зависимости от твоей цели ;-)
Изображение

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 01.06.2005 (Ср) 11:47

tyomitch писал(а):Что делает функция MSVBVM60.Zombie_Release

MSVBVM60!Zombie_Release уменьшает счетчик ссылок для объекта на 1.
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.06.2005 (Ср) 13:48

hCORe писал(а):
tyomitch писал(а):Что делает функция MSVBVM60.Zombie_Release

MSVBVM60!Zombie_Release уменьшает счетчик ссылок для объекта на 1.

Для какого объекта? Для зомби? Вах, жють :-|
Изображение

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 02.06.2005 (Чт) 9:42

tyomitch
Для сложных - выбирай в зависимости от твоей цели

Моя цель - совместимость с другими языками.
Как с остальными вопросами?

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Использование ActiveX DLL в других языках.

Сообщение Vi » 02.06.2005 (Чт) 12:55

Как лучше передавать указатель на первый элемент массива в Public процедурах, просто "m(0)"? или лучше "ByVal VarPtr(m(0))"?

Лучше не передавать "указатель на первый элемент массива" при предполагаемой передаче массива и даже не думать о таком - это не пройдёт. Этот подход используется при вызове обычных DLL-шных функций, в которых нет и грамма от СОМа и маршаллинга.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.06.2005 (Чт) 15:36

Vi, в ActiveX DLL это без разницы - там маршалинг не используется. С тем, что передавать весь массив правильнее, я полностью согласен, но вдруг у Mikle не SAFEARRAY, а обычный массив?

Mikle, для сложных типов ты в одном случае передашь указатель на копию первого элемента, в другом - указатель на его VB-вариант. Скорее всего, тебе не подходит ни то, ни другое. Для "совместимости с другими языками" сложные типы лучше не использовать вовсе, тогда будет без разницы.
Изображение

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 02.06.2005 (Чт) 19:08

Естественно, что m(0), это переменная НЕ пользовательского типа, точнее массив у меня пользовательского типа, но сам тип, в свою очередь, состоит из элементов стандатных типов, и я могу передавать первый элемент, первого элемента массива. То есть, например, я передаю ByVal VarPtr(M(0).Red), который является переменной типа Byte. Меня интересует как легче это будет декларировать из разных языков. Например в DirectX, который предназначен для использования из разных языков, есть такая процедура:
D3DX8.BufferGetData
куда данные передаются, как "Data As Any". Или всем известная CopyMemory, туда данные передаются и так, и так.
Но " просто "m(0)"? или лучше "ByVal VarPtr(m(0))"?" - это не главный вопрос. Главный, это "нет ли каких-то подводных камней", в том числе Property в C++. Вот в DirectX, почему-то, нет Property, не случайно? Я не имею ввиду ManagedDX, его из C++ не используют.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 06.06.2005 (Пн) 9:11

tyomitch писал(а):Vi, в ActiveX DLL это без разницы - там маршалинг не используется.

Если речь идёт о разных языках и о СОМ технологии, то маршаллинг будет правилом и его отсутствие - исключением. Тут не надо вводить в заблуждение.
К тому же, маршаллинг будет не внутри ActiveX DLL (если дословно понимать слово "там"), а между VB-шным кодом и кодом на другом языке. И будет определяться именно кодом последнего (т.е. кодом на другом языке).

tyomitch писал(а):С тем, что передавать весь массив правильнее, я полностью согласен, но вдруг у Mikle не SAFEARRAY, а обычный массив?

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

С другой стороны, серверный код не должен зависеть от возможностей (или особенностей) кода клиента, потому что эта информация просто НЕДОСТУПНА для сервера. Вследствие этого при проектировании и реализации сервера нужно полагать, что маршаллинг будет и передача передача последовательности ячеек передачей указателя на первый элемент будет попросту НЕВОЗМОЖНА.

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

Mikle писал(а):Например в C++, вроде бы, нет Property в привычном для нас виде. Так ли это?

Нет, не так. В С++ есть директива #import, которая генерит классы с синтаксисом Property. Т.е. будет что-то типа s = pObj->Name; и pObj->Name = s; для свойства Name. Также будут доступны обычные функции pObj->get_Name(&s); и pObj->put_Name(s);.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 06.06.2005 (Пн) 14:40

Vi
Спасибо. Особенно за информацию о Property. А стоит ли применять события, если можно обойтись и без них? И еще:

Тот, кто не выполняет это требование, потом вопит о том, почему ...


Но так сделаны многие ф-ции в Direct3D.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 06.06.2005 (Пн) 15:54

Mikle писал(а):Но так сделаны многие ф-ции в Direct3D.

Например в DirectX, который предназначен для использования из разных языков, есть такая процедура: D3DX8.BufferGetData, куда данные передаются, как "Data As Any".

Вполне возможно. Правда, у меня нет опыта использования именно DirectX в VB.

Во-первых, DirectX вряд ли написан на VB, поэтому то, как он декларирует свои интерфейсы и методы, не может быть воспроизведено при самостоятельном создании "VB6 ActiveX DLL".

Во-вторых, если VB показывает интерфейс или метод в Object Browser, не факт, что он даст его использовать в программе. Часто бывает, что он пишет, что интерфейс не является OLE совместимым и не отрабатывает.

В-третьих, я посмотрел интерфейс ID3DX8 в OLE/COM Viewer, который содержит указанный тобой метод BufferGetData
Код: Выделить всё
[odl, uuid(3AC50043-CF82-4C44-862E-B206B4F03301), helpcontext(0x00015c72), hidden]
interface ID3DX8 : IUnknown
{
...
[helpcontext(0x0001512b)] HRESULT _stdcall BufferGetData(
      [in] D3DXBuffer* Buffer,
      [in] long index, [in] long typesize, [in] long typecount,
      [in, out] void* Data);
...
};

Я сомневаюсь, что его просто использовать в VB. Если ты приведешь часть кода, который использует эту или другую подобную функцию, можно и дальше поговорить. Но в любом случае, описание "void* Data" невозможно создать на VB, а описание "long* Data" или естественное "ByRef Data As Long" передает только один элемент для изменения. То же касается всех типов в VB, кроме массивов. А это и есть SAFEARRAY.

PS
Кстати, вот такое описание на IDL
Код: Выделить всё
[id(1)] HRESULT Test2([in,out] SAFEARRAY(SAFEARRAY(VARIANT)) * v);
приводит к появлению вот такого (смешного и неработающего) описания в Object Browser
Код: Выделить всё
Sub Test2(v() As () As Variant)
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.06.2005 (Пн) 16:10

Vi
void* - это VB-шный Any. Вот, собственно, и всё.
А с помощью ByRef Data As Long можно передать сколько угодно массивов...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 06.06.2005 (Пн) 16:18

Vi
Конечно DX написан не на VB :lol:
Вот типичный пример использования Buffer8SetData:
D3DVertexBuffer8SetData vBuffer, 0, SizeOfVertex * (NumTri * 3), 0, Vert(0)
где поле, где стоит Vert(0) просит "DATA As Any". В моем случае там стоит первый элемент массива, тип не имеет значения, похоже на CopyMem и смысл почти тот же.
если VB показывает интерфейс или метод в Object Browser, не факт, что он даст его использовать в программе. Часто бывает, что он пишет, что интерфейс не является OLE совместимым и не отрабатывает.

В DX такого не замечал. Хотя там есть моменты, явно неудобные для VB. Например некоторые методы требуют пераметром Long, а работают с ним, как с Single (Float). Например для задания плотности тумана нужно вычислить плотность в переменной типа Single, перенести побайтно ее содержимое в Long и ее передавать. В СИ проще - они плюют на совместимость типов и передают указатель на переменную Float, подозреваю, что и DX дальше работает с ней, как с Float.
И весь этот гиморрой для того, чтобы не использовать свойство вместо метода. А в managed DX уже все нормально, есть свойства, но его не применяют из C++.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 161

    TopList