Вообще-то я этот вопрос некоторое время назад задавал, но все же - вдруг свежие
мысли появились...
Вкратце - хочу аналог Сшной операции "->" - обращение к элементу структуры по
ссылке.
Подробнее. Получаю указатель на память, и хочу работать через него со
структурой. ВБ гарантированно это умеет - ибо именно ОНО происходит в этом
случае:
type tMy
l1 as long
l2 as long
end type
sub test(byref tt as tMy)
tt.l2=0' это обращение идет именно по ссылке!
end sub
Однако мне так и не удалось подсунуть свой указатель. Пять бубнов порвал -
ничего не получается :( Пока структурка была маленькая - можно было гонять ее
туда-сюда целиком через CopyMemory, а сейчас она распухла, и все начало
тормозить.
Помогите, кто чем может...
--
With best regards
Dmitry Viazowkin
21 Apr 04 12:47, Dmitry Viazowkin wrote to all:
DV> type tMy
DV> l1 as long
DV> l2 as long
DV> end type
DV> sub test(byref tt as tMy)
DV> tt.l2=0' это обращение идет именно по ссылке!
DV> end sub
DV> Однако мне так и не удалось подсунуть свой указатель. Пять бубнов порвал -
DV> ничего не получается :( Пока структурка была маленькая - можно было гонять
DV> ее туда-сюда целиком через CopyMemory, а сейчас она распухла, и все начало
DV> тормозить.
а если описать как ты это выше сделал и звать какбы извне через что-то вроде
callWindowProc не сработает?
Anton
> а если описать как ты это выше сделал и звать какбы извне через что-то вроде
> callWindowProc не сработает?
Преведи для старого больного меня на понятный язык, плз ;) Желательно с куском
кода - а то я об этот вопрос остатки мозгов сломал...
DV> Однако мне так и не удалось подсунуть свой указатель. Пять бубнов
DV> порвал - ничего не получается :( Пока структурка была маленькая - можно
DV> было гонять ее туда-сюда целиком через CopyMemory, а сейчас она
DV> распухла, и все начало тормозить.
Вариант 1 (не проверял) задекларируй VarPtr из MSVBVM60, чтобы принимала
указатель, а возвращала структуру, и вызывай.
Вариант 2 (от продвинутых чуваков) объяви массив из одной такой структуры, и
меняй указатель на данные в SAFEARRAY.
Вариант 3 (для Win9x) задекларируй Callback4 из KERNEL32, чтоб принимала
указатель, и вызывай свою функцию, принимающую структуру.
Если не поможет, могу ещё идей сгенерировать...
With best regards, A. Skrobov. E-mail: tyom...@r66.ru
--
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
> Вариант 1 (не проверял) задекларируй VarPtr из MSVBVM60, чтобы принимала
> указатель, а возвращала структуру, и вызывай.
Я проверял, в первом десятке попыток. Когда возвращаешь структуру - надо
вернуть ИМЕННО структуру, а не указатель на нее. GPF
> Вариант 2 (от продвинутых чуваков) объяви массив из одной такой структуры, и
> меняй указатель на данные в SAFEARRAY.
Что будет при попытке VB порулить этим массивом??? Ежели указатель получен от
Alloc - еще куда ни шло, а если от MapViewOfFile? Хотя - это что-то свежее... А
попробую-ка вернуть Vector из таких структур, VB ими не рулит - а юзать умеет.
> Вариант 3 (для Win9x) задекларируй Callback4 из KERNEL32, чтоб принимала
Отпадает - надо честно для Win32.
> Если не поможет, могу ещё идей сгенерировать...
Давай... на безрачье и рыбу раком...
> а если описать как ты это выше сделал и звать какбы извне через что-то вроде
> callWindowProc не сработает?
Ага, попробовал - и сделал, и даже получилось. Вот только пользы от этого - 0.
Потому что - мне надо обращаться к разделяемой структуре, примерно таким
образом:
''' участок кода, где-то есть описание dim sm as tShare
''' hMap - тот самый указатель на разделяемую память.
LockMutex ShareMutex
CopyMemory sm, ByVal hMap, Len(sm) ' copy from mem to struct
sm.strData = s
sm.fData = True
CopyMemory ByVal hMap, sm, Len(sm) ' copy back to map
ReleaseMutex ShareMutex
'''
а так мне придется создавать миллион функций - на каждое обращение по
указателю... да еще и звать их
---
result = CallWindowProc(AddressOf Get3, hMap, 0, 0, 0)
---
Бррр...
Хотелось бы чуда! А именно: внутри функции с описанием
sub SomeSub(byref sm as tShare,...)
сделать что-нибудь типа
SomeMagicProc(sm,hMap)
и после этого чтобы sm показывал туда, куда надо... Я не слишком много хочу???
21 апр 04 года ты писал(а) к All:
[...skipped...]
DV> type tMy
DV> l1 as long
DV> l2 as long
DV> end type
DV> sub test(byref tt as tMy)
Может здесь имеет смысл объявить промежуточную переменную типа
Dim xTMy as tMy
DV> tt.l2=0' это обращение идет именно по ссылке!
...и обращаться уже как к xTMy.l2
DV> end sub
DV> Однако мне так и не удалось подсунуть свой указатель. Пять бубнов
DV> порвал - ничего не получается :( Пока структурка была маленькая -
DV> можно было гонять ее туда-сюда целиком через CopyMemory, а сейчас она
DV> распухла, и все начало тормозить.
[...skipped...]
I'll be back, Dmitry !
http://www.caligari.zp.ua - реальная психологическая и психиатрическая помощь.
Анонимно. Пока бесплатно.
> Dim xTMy as tMy
>
> ...и обращаться уже как к xTMy.l2
А смысл? Такое обращение идет к ЛОКАЛЬНОЙ переменной - а мне как бы совсем не то
надо. Ты вопрос-то понял?
С этим вариантом оказалось совсем смешно - в VB не существует способа получить
адрес массива! varptr(arr) обламывается при компиляции, а varptr(arr(0))
возвращает совсем не то. В качестве кривого объезда заюзал
Declare Function ArrPtr Lib "msvbvm60.dll" Alias "VarPtr" (arr() As Any) As
Long
так оно возвращает адрес ссылки на SafeArray... Пришлось раз'именовывать через
CopyMemory/ После этого зверства заработало, по кр. мере при подстановке на
локальную область памяти. Пробую дальше...
22 Apr 04 02:10, Dmitry Viazowkin wrote to me:
>> а если описать как ты это выше сделал и звать какбы извне через что-то
>> вроде callWindowProc не сработает?
DV> Ага, попробовал - и сделал, и даже получилось. Вот только пользы от этого
DV> - 0. Потому что - мне надо обращаться к разделяемой структуре, примерно
DV> таким образом:
DV> ''' участок кода, где-то есть описание dim sm as tShare
DV> ''' hMap - тот самый указатель на разделяемую память.
DV> LockMutex ShareMutex
DV> CopyMemory sm, ByVal hMap, Len(sm) ' copy from mem to struct
DV> sm.strData = s
DV> sm.fData = True
DV> CopyMemory ByVal hMap, sm, Len(sm) ' copy back to map
DV> ReleaseMutex ShareMutex
DV> '''
DV> а так мне придется создавать миллион функций - на каждое обращение по
DV> указателю... да еще и звать их
DV> - ---
DV> result = CallWindowProc(AddressOf Get3, hMap, 0, 0, 0)
DV> - ---
DV> Бррр...
DV> Хотелось бы чуда! А именно: внутри функции с описанием
DV> sub SomeSub(byref sm as tShare,...)
DV> сделать что-нибудь типа
DV> SomeMagicProc(sm,hMap)
DV> и после этого чтобы sm показывал туда, куда надо... Я не слишком много
DV> хочу???
Дык я именно это и имел в виду. Если ты говоришь, что VB работает со
структурами по указателю, до должно сработать что-то типа такого:
sub SomeSub(byref sm as tShare)
LockMutex ShareMutex
'CopyMemory sm, ByVal hMap, Len(sm) ' а этого не надо
sm.strData = s
sm.fData = True
'CopyMemory ByVal hMap, sm, Len(sm) ' и этого не надо
ReleaseMutex ShareMutex
end sub
ну и звать ее как
result = CallWindowProc(AddressOf SomeSub, hMap, 0, 0, 0)
разумеется работоспособность этого зависит от того как VB отрабатывает byref sm
as TShare. Если он ожидает там именно адрес первого элемента структуры, то все
должно сработать. Проверять пока некогда, сорри.
Anton
> CopyMemory/ После этого зверства заработало, по кр. мере при подстановке на
> локальную область памяти. Пробую дальше...
Попробовал. Работает. Причем даже сверх желаемого - ибо удалось создать
глобальную переменную для обращения к этой памяти. Главное, перед выходом не
забыть починить массив...
Так что спасибо всем - вопрос снят.
> ну и звать ее как
>
> result = CallWindowProc(AddressOf SomeSub, hMap, 0, 0, 0)
>
> разумеется работоспособность этого зависит от того как VB отрабатывает byref
sm
> as TShare. Если он ожидает там именно адрес первого элемента структуры, то все
> должно сработать. Проверять пока некогда, сорри.
Не, это, конечно, все работает - но уже во вложеных функциях. А мне надо на
уровень выше.
Ладно, вопрос снят - идея с ковырянием массива оказалась очень правильной, и
удалось сделать ГЛОБАЛЬНУЮ переменную для обращения к этой памяти.
DV> Попробовал. Работает. Причем даже сверх желаемого - ибо удалось создать
DV> глобальную переменную для обращения к этой памяти. Главное, перед
DV> выходом не забыть починить массив...
DV> Так что спасибо всем - вопрос снят.
Расплываюсь в довольной улыбке... Рад был помочь :-)
> Расплываюсь в довольной улыбке... Рад был помочь :-)
Благодабря (с) нашей уважаемой компании, и особенно лично товарища A. Skrobov-а,
нам удалось поднять межпроцессное взаимодействие на новую, ранее недосягаемую
высоту! (с) лозунг
Все удовольствие выглядит как
------------
Public mSh(0 To 0) As tShare ' подстановку указателя удается осуществить только
в массиве...
Private tmpArrPointer As Long ' старый адрес данных массива
private Declare Function ArrPtr Lib "msvbvm60.dll" Alias "VarPtr" (arr() As Any)
As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any,
pSource As Any, ByVal ByteLen As Long)
Private Sub LinkMapArray(ByVal pMem As Long)' на входе, после получения
указателя
Dim aptr As Long
CopyMemory aptr, ByVal ArrPtr(mSh()), 4 ' переписываем адрес ссылки на
массив
CopyMemory tmpArrPointer, ByVal (aptr + 12), 4 ' запоминаем старый указатель
CopyMemory ByVal (aptr + 12), hM, 4 ' исправляем указатель данных на маппинг
DbgBox "hMap=" & hMap & " &mSh(0)=" & VarPtr(mSh(0)) & " & mSh(0).sz=" &
VarPtr(mSh(0).sz)
End Sub
Private Sub RestoreMapArray()' перед выходом
Dim aptr As Long
CopyMemory aptr, ByVal ArrPtr(mSh()), 4 ' переписываем адрес ссылки на
массив
CopyMemory ByVal (aptr + 12), tmpArrPointer, 4 ' восстанавливаем старый
указатель
End Sub
-----------
А ведь два года вопрос висел...