Модераторы: mihanik
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Существует ли аналог **ptr в VBA? 
V
    Опции темы
Dementor
Дата 4.9.2015, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Всем привет!
Сразу уточню, что речь пойдет не о VBA для Office, а о VBA для Microstation, хотя сути это вообще не меняет, т.к. VBA он везде VBA.

Есть вот такая сишная функция FnScanGetMrk( BYTE **Tbl), которая выполняет две задачи: возвращает целочисленное значение и заполняет динамический массив указателей на данные.

Вызов функции осуществляется с помощью другой функции (это просто ради пояснения, так сказать лирическое отступление), которая принимает в качестве параметра название вызываемой функции и ее параметры, например вот так это может выглядеть:
Код

Dim Res
Dim vCommand As String
vCommand = "FnScanGetMrk(" & TblPointer & ")"
Res = GetCExpressionValue(vCommand)


Соответственно не понятно, что именно необходимо передать в качестве TblPointer для FnScanGetMrk( BYTE **Tbl). Если бы речь шла о статическом массиве, размер которого заведомо известен (есть там и такие функции), то используется просто указатель на первый элемент массива, например, VarPtr(Array(0)) и все отлично работает.

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

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

Буду рад и искренне благодарен за любую помощь и любые отзывы.
PM MAIL   Вверх
Romikgy
Дата 4.9.2015, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: нет
Всего: 146



VarPtrArray не ? 
PS имхо васик не задумывался для работы с указателями... 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Dementor
Дата 4.9.2015, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Romikgy, к сожалению нет.

Это было проверено уже давно вот таким образом:
Код

Dim ExprRes
Dim Tbl() As Byte
Dim TblPointer As Long

TblPointer = VarPtrArray(Tbl)
vCommand = "FnScanGetMrk(" & TblPointer & ")"
ExprRes = GetCExpressionValue(vCommand)
Debug.Print "FnScanGetFlg = " & LBound(Tbl) & " --> " & UBound(Tbl) & " ExprRes = " & ExprRes


Результат подобных действий приводит просто к Subscript out of range.

То, что сам язык для этого не задумывался это понятно, но хочется все-таки разобраться в том можно ли все-таки использовать или 100% нет и надо писать какие-то свои DLL и т.п.
PM MAIL   Вверх
Akina
Дата 4.9.2015, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Dementor, что, по-Вашему, получится в переменной vCommand после выполнения 
Цитата(Dementor @  4.9.2015,  15:20 Найти цитируемый пост)
vCommand = "FnScanGetMrk(" & TblPointer & ")"

???
Вы в сях тоже указатели передаёте функциям, преобразовав их в десятичное число?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Dementor
Дата 4.9.2015, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



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

Для примера:
Код

    Dim ExprRes
    Dim Sel(255) As Byte
    
    Dim vCommand As String
    Dim i As Integer

    vCommand = "FnScanSelectClasses(" & VarPtr(Sel(0)) & ")" 'Значение VarPtr(Sel(0)) можно передать и через отдельную переменную, разницы никакой

    ExprRes = GetCExpressionValue(vCommand)
    
    For i = 0 To 255
        If Sel(i) = 1 Then
            Debug.Print CStr(i) & " = " & Sel(i)
        End If
    Next i

При этом в чистом виде сама функция в сях выглядит так: FnScanSelectClasses( char *Sel);
PM MAIL   Вверх
Akina
Дата 4.9.2015, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Dementor @  4.9.2015,  17:28 Найти цитируемый пост)
в сях все передается так, как должно передаваться

Ты хочешь сказать, что в сях валиден вызов типа 
Код

ExprRes = GetCExpressionValue('FnScanSelectClasses(12345678)');
где 12345678 - это десятиричное значение адреса указателя
???


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Dementor
Дата 4.9.2015, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



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

Вопрос ведь в том, что я лично не понимаю, что именно требуется передать через VBA. Поэтому и прошу помощи и разъяснения.
PM MAIL   Вверх
Akina
Дата 4.9.2015, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



GetCExpressionValue - это тоже функция, импортируемая из какой-то библиотеки?
Как она вызывается в программе на тех же сях?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Dementor
Дата 4.9.2015, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Akina, GetCExpressionValue доступна по-умолчанию в VBA для Microstation. 

Если интересует именно описание, то вот выдержка их хэлпа:
GetCExpressionValue Method
Returns the result of evaluating the expression.. 
Syntax
VARIANT = object.GetCExpressionValue (CExpression [, MdlApplicationName]) 

The GetCExpressionValue method syntax has these parts:
object - A valid object.
CExpression - A String expression. Any legal MDL expression.
MdlApplicationName - Optional. A String expression. The MDL application that published the variable referenced by the CExpression argument. This is important only if more than 1 MDL application has published a variable with that name.

И немного в качестве дополнения. Та функция о которой я пишу даже в том виде, в котором есть сейчас, хоть что-то да выдает.

Это сообщение отредактировал(а) Dementor - 4.9.2015, 17:30
PM MAIL   Вверх
Akina
Дата 4.9.2015, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Dementor @  4.9.2015,  18:03 Найти цитируемый пост)
GetCExpressionValue доступна по-умолчанию в VBA для Microstation. 

Цитата(Dementor @  4.9.2015,  18:03 Найти цитируемый пост)
CExpression - A String expression. Any legal MDL expression.

Посмотрел справку по этой функции. Обычный Eval().
Попробуй вызвать его в форме 
Код

GetCExpressionValue("FnScanSelectClasses(?????????)")

где вместо знаков вопроса будет стоять значение-литерал. Если удастся - станет понятно, в каком формате нужно отдавать адрес.

Либо попробуй объявить этот самый Sel() как глобальный (во всяком случае - видимый самОй функции GetCExpressionValue) и вызвать именно как
Код

GetCExpressionValue("FnScanSelectClasses(VarPtr(Sel(0)))")



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Dementor
Дата 4.9.2015, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



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

Вопрос же возникает когда в качестве параметра требуется указать массив динамический, например в случае функции FnScanGetMrk( BYTE **Tbl). Т.е. не понятно как представить BYTE **Tbl в VBA. Передать просто VarPtrArray не получается, т.е. передать то можно и функция даже вернет количество данных в памяти (хотя там еще вопрос, что за количество должно вернуться, но по логике именно количество маркированных данных), но массив останется пустой и всякие UBound и LBound будут выдавать ошибку.
PM MAIL   Вверх
Akina
Дата 4.9.2015, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Dementor @  4.9.2015,  22:22 Найти цитируемый пост)
Вопрос же возникает когда в качестве параметра требуется указать массив динамический

Неважно, статический массив или динамический. Важно, что:
1) В момент передачи его функции он уже должен быть инициализирован, причём размером не менее помещаемых в него данных;
2) Его размер с точки зрения среды исполнения не изменится;
3) Если сама функция не передаст кроме массива ещё и количество помещённых в него данных, определить, сколько именно данных помещено - невозможно.
Функция просто помещает данные в непрерывный блок памяти, который начинается с переданного ей адреса. И что это - сишный массив, строковая переменная, VBA-массив - ей абсолютно похрен, равно как и похрен, не гавкнется ли при этом процесс или даже ось.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Dementor
Дата 4.9.2015, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Akina, в общем забил я на массивы и т.п.

Код

Dim Tbl As Long
Dim Coordinate As Long
ExprRes = GetCExpressionValue("FnScanGetPnt(" & VarPtr(Tbl) & ")")
CopyMemoryToVBA Coordinate, Tbl, 4
Debug.Print Coordinate


Банально получаем адрес первого значения, далее двигаясь с известным сдвигом получаем все, остальное для всех данных.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование, связанное с MS Office"
mihanik staruha

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами



  • Несанкционированная реклама на форуме запрещена
  • Пожалуйста, давайте своим темам осмысленный, информативный заголовок. Вопль "Помогите!" таковым не является.
  • Чем полнее и яснее Вы изложите проблему, тем быстрее мы её решим.
  • Оставляйте свои записи в "Книге отзывов о работе администрации"
  • А вот тут лежит FAQ нашего подраздела


Если Вам понравилась атмосфера форума, заходите к нам чаще!
С уважением mihanik и staruha.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование, связанное с MS Office | Следующая тема »


 




[ Время генерации скрипта: 0.0799 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.