• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Передача констант через динамически подгружаемую библиотеку

leiba

Well-known member
18.06.2010
49
0
BIT
3
Всем привет!
Создал LS-библиотеку, общую для нескольких баз системы. Специфику же каждой базы определил через константы в персональной библиотеке. Если просто подключать персональную библиотеку в Options общей библиотекеи, то при модификации общей библиотеке требуется перекомпиляция в каждой БД.
Подумал, что подключая персональную библиотек динамически через execute, я обойду эту проблему.
Написал следующую функцию в общей библиотеке:
Код:
Function getGlobalVar(vName As String) As String
'! vName - имя константы
Dim ret as String

Execute ({Use "Setup.Lib"
ret = } +vName)
getGlobalVar = ret
'! конец функции
End Function
Однако, функция ничего не возвращает :)

Решил эту задачу созданием класса в персональной библиотеке и метода в нем, который возвращает нужную константу.
Вот класс
Код:
Class SetupFields
Sub New
End Sub

Property Get getConstant(xName As String) As String
'! переменные
Dim xRet As String

Select Case xName
Case "CFGFIELD_NSI": xRet = CFGFIELD_NSI
Case "CFGFIELD_LOG": xRet = CFGFIELD_LOG
Case "CFGFIELD_INVOICE": xRet = CFGFIELD_INVOICE
Case Else :	xRet = {}	
End Select
getConstant = xRet
'! конец property
End Property
End Class
И вот какой стал вызов в общей библиотеке
Код:
Function getGlobalVar(vName As String) As String
'!vName - имя константы

Execute ({Use "Setup.Lib"
Set ret = New SetupFields})
getGlobalVar = ret.getConstant(vName)
'! конец функции
End Function
Такое решение мне не очень нравится.
Может у кого будут другие идеи?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
экзекьют работает только с public переменными внешнего кода - если вопрос был про это
компилится он налету и модуль будет временным (по окончании "уничтожится")
 
N

nvyush

Встречал такое решение проблемы необходимости перекомпиляции библиотек при изменении констант — не использовать константы, а использовать глобальные переменные, инициализируемые в Initialize. В Вашем случае в персональных библиотеках объявляете глобальные переменные, инициализируете их нужными значениями, в общей библиотеке используете эти переменные с индивидуальными значениями (нужна будет фейковая персональная библиотека в базе-шаблоне).
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Либа
Код:
Public Const p = "TEST"
Sub Initialize

End Sub

Sub Terminate

End Sub

Public Function MyParam As Variant

MyParam = "Проверка"

End Function
вызов по кнопке из формы
Код:
Sub Click(Source As Button)
Dim vName As String
Dim script As Variant

vName = "MyParam"

script = | Use "test" 
ret = | + vName

retcode% = Execute (script )
Messagebox(ret)	
End Sub
Public ret As String - в секции Declaretion ФОРМЫ
 
T

turumbay

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

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
ну так а за какие рамки? это же просто результат работы твоих функций?
Просто без Public ты будешь получать пустое значение.
Или боишься что можно перехватить значение?
 
N

nvyush

Public ret As String - в секции Declaretion ФОРМЫ
А, собственно, зачем? Проще вынести в Declaration самой библиотеки, только назвать "поприличнее", например, GLOBAL_RETURN_VALUE (чтоб случайно не переопределить где-нибудь).
Но в целом согласен с turumbay — лучше в настройки.
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
А, собственно, зачем? Проще вынести в Declaration самой библиотеки, только назвать "поприличнее", например, GLOBAL_RETURN_VALUE (чтоб случайно не переопределить где-нибудь).
Но в целом согласен с turumbay — лучше в настройки.
В саму библиотеку нельзя. Если указано Option Declare - это вообще работать не будет, а без декларации в форме будет пустое значение.
Тут разве что создавать отдельную библиотеку с публичными переменными
 
N

nvyush

В саму библиотеку нельзя. Если указано Option Declare - это вообще работать не будет, а без декларации в форме будет пустое значение.
Это ещё почему??? Поместить сию переменную как Public в (Declarations) той же самой библиотеки, где функция getGlobalVar. Фактически эту переменную только та функция и использует.
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Это ещё почему??? Поместить сию переменную как Public в (Declarations) той же самой библиотеки, где функция getGlobalVar. Фактически эту переменную только та функция и использует.
Ну не знаю... у меня не получилось.
Тут же главная фишка - не использовать явную загрузку библиотеки, а так как ты предлагаешь получается что GLOBAL_RETURN_VALUE будет локальной для данной формы

Вопрос снимается. Я отталкивался от формы, а не от библиотеки-обвязки
 

leiba

Well-known member
18.06.2010
49
0
BIT
3
В общем, пока остановился на таком решении.
В персональной библиотеке
Код:
'Description
Option Public
Option Declare

Const CFGFIELD_NSI = {FileSetup}
Const CFGFIELD_LOG = {}
Const CFGFIELD_INVOICE = {FileInvoice}

Dim xRet As String

Class SetupFields
Sub New
End Sub

Property Get getConstant(xName As String) As String
'! переменные
'! обработчик ошибок
On Error Goto ErrH
If False Then
ErrH: 			Error Err, Error$ & Chr(10) & Getthreadinfo(1) & " (" & Erl & ")"
End If
'! начало property
Execute ({xRet = }+xName)
getConstant = xRet		
'! конец property
End Property
End Class
Общая библиотека
Код:
'Description
Dim ret As Variant
Function getGlobalVar(vName As String) As String
'! обработчик ошибок
On Error Goto ErrH
If False Then
ErrH: 		Error Err, Error$ & Chr(10) & Getthreadinfo(1) & " (" & Erl & ")"
End If
'! начало функции
If IsEmpty(ret) Then
Execute ({Use "Setup.Lib"
Set ret = New SetupFields})
End If
getGlobalVar = ret.getConstant(vName)
'! конец функции
End Function
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!