kibernetics > "мне нравится в бейсике простоту реализации кода" Ну положим бэйсик не проще паскаля (Delphi), а вот "подебильнее" и потормознее это точно ) (этот бэсик меня просто бе-е-сит ) > "вот если бы научится использовать апи функции в том же басике" Дык, учись ) Во-первых, ты не на тот форум забрался - лучше бы погуглил и нашел братьев по разуму (или по несчастью . Наверняка есть готовые API-шные либы (tlb) для васика или модули импорта API-функций Во-вторых, для конкретной задачки и самому ничего не стоит объявить несколько функций API. Берешь объявление функции из MSDN, вставляешь в свой проект и "разукрашиваешь" в соответствии с "васькиными" требованиями. Например импорт ReadFile будет выглядеть так: Код (Text): Declare Function ReadFile Lib "kernel32.dll" ( _ ByVal hFile as Long, _ ByVal lpBuffer as Long, _ ByVal nNumberOfBytesToRead as Long, _ ByRef nNumberOfBytesRead as Long, _ ByVal lpOverlaped as Long) as boolean Все In-параметры, включая указатели и строки передаются по значению (ByVal) Out-параметры (кроме строк) - по ссылке ByRef. В данном случае в API должен передаваться указатель lpNumberOfBytesRead на dword, в который будет записано число прочитанных байт, поэтому мы просто объявлем его ByRef Ну и т.д. и т.п.
kibernetics Да, если переход -- на Lisp. В случае перехода на pascal/delphi получишь только позитивные ощущения. Переход на C сравним с переходом на ASM.
Идем в Add-In Manager Включаем VB 6 API Viewer все объявления для Win API берем из него, для этого собственно и предназначен
cresta Тут вроде речь идет не об освоении VCL, а об языке программирования, так что не понятно от чего должна быть тошнота. Вот когда я рассматриваю некоторые сорцы на Си++, чувствую легкое головокружение: <font size=1> Код (Text): ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this); if (_Ok) { // state okay, use facet to insert const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); ios_base::fmtflags _Bfl = ios_base::flags() & ios_base::basefield; long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex) ? (long)(unsigned int)_Val : (long)_Val; _TRY_IO_BEGIN if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Tmp).failed()) _State |= ios_base::badbit; _CATCH_IO_END } </font><!--size--> А сколько замечательных граблей ждет новичка, при освоении оператора ==... Впрочем подобные разговоры, опять приведут к холивару и кучи флейма, так что возвращаться к нему больше не буду.
cresta, alpet Вот уж действительно незачем в очередной раз затевать бессмысленную дискуссию Pascal vs C++ А "позитивные ощущения" нужно понимать не вообще, а с точки зрения перехода с васика на паскаль, т.к. с точки зрения синтаксиса у них больше сходства, чем различий (чего не скажешь о С++) Asterix Видать ты знаком с этим чудо языком Может подскажешь автору топика и мне заодно - есть ли в васике приведение типов и работа с указателями. В частности: допустим используя API выделили блок памяти и прочитали в него кусок файла - как теперь на васике обратится к первому байту или дворду блока ?
leo только на уровне минимальной программы, причем подглядывая в доку Есть такая книжка(в сети точно есть в doc формате): Евангелос Петрусос Visual Basic 6 Руководство разработчика Перевод с английского под редакцией Ю.М. Зорина Том 2 в ней немного про работу с Win API в VB 6 один из подразделов называется • Передача аргументов по значению и по ссылке копипастить не решился
Да есть полно примеров работы с файлами на VB, стандартно примерно так: Код (Text): Dim buf() As Byte Open filename For Binary Put #filename,,buf Close filename Или через API: Код (Text): ReadFile hFile, buf, 100, dwBytesRead, ByVal 0& К первому байту обратится через buf(0), но точый код я уже сам не напишу, несколько лет VB не запускал
Asterix, bogrus С передачей аргументов и обращением к "родному" массиву и так ясно - в любом хэлпе к VBA MS Office расписано, да и в MSDN кое что есть. Мне интересно (для общего развития как обращаться к динамическому блоку памяти, например: Код (Text): Dim pMem as long,... pMem = MapViewOfFile(...) и как теперь с этим pMem работать ? Хотя возможно kibernetics знает, но молчит
Почти для всех API-функций необходимо передавать параметры по значению. Только те параметры, которые изменяются самой функцией, необходимо передавать по ссылке. По умолчанию, Visual Basic передает аргументы по ссылке, поэтому для передачи аргументов по значению необходимо использовать ключевое слово ByVal.
с указателями просто так не работается. надо копировать (RtlMoveMemory) в промежуточную переменную (буфер), и работать с буфером. Затем обратно буфер копировать на место Примерно так: Код (Text): Dim buffer(1023) As Byte RtlMoveMemory buffer(0), pMem+offset, LenB(buffer) ;тут что-нибудь сделали с буфером ;и затем копируем на место RtlMoveMemory pMem+offset ,buffer(0), LenB(buffer) Таким же образом работается и с указателями, передаваемыми например в WndProc как lParam. Копия в соотвествующего типа локальную переменную, обработка переменной, и при необходимости копия обратно по адресу в lParam.
Вот вариант попроще: Код (Text): Declare Function RtlMoveMemory Lib "kernel32.dll" ( _ Destination() As Byte, _ Source As Long, _ ByVal Length As Long) As Long Declare Function LocalAlloc Lib "kernel32.dll" ( _ ByVal uFlags As Long, _ ByVal uBytes As Long) As Long Declare Function LocalFree Lib "kernel32.dll" ( _ ByVal hMem As Long) As Long Private var_ptr(6) As Long Sub Main() Dim pMem, i As Long Dim Array1() As Byte pMem = LocalAlloc(0, 8) Call Bind(Array1, pMem) ' Работаем с pMem через Array1 Array1(5) = 10 Call Unbind(Array1) LocalFree (pMem) End Sub Sub Bind(Some_Array() As Byte, ByVal hMem As Long) Dim i As Long i = VarPtr(var_ptr(0)) var_ptr(3) = hMem Call RtlMoveMemory(Some_Array, i, 4) End Sub Sub Unbind(Some_Array() As Byte) Dim i As Long i = 0 Call RtlMoveMemory(Some_Array, i, 4) End Sub Достаточно вызвать функцию Bind чтобы превратить укзатель типа Long в динамический массив. Unbind желательно вызывать перед освобождением динамического массива. ЗЫ: Я тут LocalAlloc вместо MMF использую, чтоб кода было меньше. ЗЫЫ: В .Net это работать не будет. ЗЫЫЫ: Вот ещё статья в тему про указатели в VB и почему с ними "трудно" работать.
Quantum Идея понятна, вот только реализацию ты привел чересчур упрощенную При обращении к массиву VB проверяет попадание индекса в допустимый диапазон, поэтому кроме указателя на память нужно еще устанавливать число элементов массива SAFEARRAY.rgsabound[0].cElements - в твоем варианте var_ptr(4). Ну и разумеется если использовать такой подход "всерьез и надолго", то конечно нужны доп.навороты - проверка переданного указателя, замена глобальной переменной var_ptr на динамическую и т.п. PS: набрел на пару ссылочек: Сущность массивов в VB, Variant и SafeArray PSS: Мы тут понимаешь рассуждаем ради спортивного интереса, а куда интересно kibernetics пропал ? Не иначе как последовал доброму совету и увяз в непролазных дебрях С++ ? )))
leo нет. я незнаю. сам пытаюсь вывести пацанов, чтоб рассказали. кто-то пробовал файл-маппинг. в басике непонятно как использовать указатели.
не хочу скрывать, я еще паралельно задал вопрос по васику здесь: http://bbs.vbstreets.ru/viewtopic.php?p=6602000 и здесь: http://bbs.vbstreets.ru/viewtopic.php?t=25205 может кому-то будет интересно.
kibernetics > "задал вопрос по васику здесь ..." Насколько я понимаю, первый вопрос по обработке файла решен и значит отпадает > "в басике непонятно как использовать указатели" В первом приближении уже понятно Если начнешь разбираться сам и задавать конкретные вопросы, то может что-то сдвинется с места. Под лежачий камень вода не течет )
leo Кажется, в .Net уже убрали поддержку VarPtr. Так что использовать "такой подход всерьез и надолго" уже не получится. Да и работает он по понятным причинам только в скомпилированном экзешнике. Да, надо было глубже трассировать. Виноват. kibernetics Не помню всплывал такой совет уже или нет... Можно сделать обработку файлов на C/Delphi/asm/etc, скомпилировать в DLL и потом использовать эту DLL в приложении на VB. Лёгкое надругательство над линкером VB позволяет использовать даже статические либы.
Еще здесь надо использовать MMX/SSE для повышения быстродействия, да так и удобней копировать данные размером 512 байт.