Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > Передача буфера типа String в API


Автор: Akina 31.8.2005, 15:21
помню там получаем адрес дескриптора стринговой переменной, из которого собсно выдираем адрес тела стринга... но вот вылетело - а найти что-то не могу...

Автор: boevik 31.8.2005, 15:34
К примеру:
Код

Dim sz as Integer
Dim str as String
sz = 255
str = Space(sz)
sz= GetWindowsDirectory(str, sz)

Автор: __Sergey__ 31.8.2005, 15:46
или так
Код

Dim sz as Integer
Dim str as String
str = String(255,0)
sz= GetWindowsDirectory(str, 255)

Автор: Mephisto 31.8.2005, 15:47
Код

sub Left
    dim strString$

    MsgBox myFunction(ByVal strString)
End Sub

Function MyFunction (byVal strString&) as String
    MyFunction=cstr(strString)
End Function

Ты об этом????

Автор: __Sergey__ 31.8.2005, 15:55
все зависит от того, что АПИ принимает:
- ОЛЕ-строку ( As String);
- указатель на строку(As Long)

Для последнего StrPtr(buf).

Автор: Akina 31.8.2005, 16:00
Все намного хуже. Надо передавать буфер в API, причем ByRef, причем описанный как Any. Типа как lpBuffer в

Код

Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
                                          lpBuffer As Any, _
                                          ByVal nNumberOfBytesToRead As Long, _
                                          lpNumberOfBytesRead As Long, _
                                          lpOverlapped As Long) As Long


Я помню, там получался дескриптор строки (StrPtr), а потом строился ее адрес при помощи Peek в переменной типа Long... вроде бы...

Автор: __Sergey__ 31.8.2005, 16:02
да, еще байтовый массив
Код

Dim sz as Integer
Dim str () As Byte
sz= GetWindowsDirectory(str(0), 255)

Добавлено @ 16:08
В ReadFile можно использовать и байтовый массив
и выделить буфер с помошью String$

Автор: Plamenk 31.8.2005, 16:38
Может быть это поможет!

Код

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
   Destination As Any, Source As Any, ByVal Length As Long)

Function BSTRtoLPSTR(sBSTR As String, b() As Byte, lpsz As Long) As Long

' Input: a nonempty BSTR string
' Input: **undimensioned** byte array b()
' Output: Fills byte array b() with ANSI char string
' Output: Fills lpsz with a pointer to b() array
' Returns byte count, not including terminating null
' Original BSTR is not affected

Dim cBytes As Long
Dim sABSTR As String

cBytes = LenB(sBSTR)

' ReDim array, with space for terminating null
ReDim b(1 To cBytes + 2) As Byte

' Convert to ANSI
sABSTR = StrConv(sBSTR, vbFromUnicode)

' Point to BSTR char array
lpsz = StrPtr(sABSTR)

' Copy the array
CopyMemory b(1), ByVal lpsz, cBytes + 2

' Point lpsz to new array
lpsz = VarPtr(b(1))

' Return byte count
BSTRtoLPSTR = cBytes

End Function

Автор: Kergan 1.9.2005, 16:23
когда делал DLL-ку на C++, там тоже надо было передать BYREF строковый буффер (использовал dll в Basic). Так вот. В функции dll заголовок такой
ExtendedEnumProcs(char* buff)
для тех кто не в курсе char* - почти строка, это указатель на нулевой символ.
Когда юзал в си, все норм, а когда перенес в баську, объявил так:
[code=vb]
(byref buff as string)
[/code=vb]
Испытал и вылетел нафиг... Еще раз... потом еще.
Оказалось, что СТРОКУ передавать надо BYVAL - все равно передаст УКАЗАТЕЛЬ.
ну и само собой ее надо заполнять перед передачей функцией Space...
попробуй в декларации вместо
[code=vb]
lpBuffer as Any
[/code=vb]
поставить
[code=vb]
ByVal lpBuffer as string
[/code=vb]
Можа прокатит...

Автор: oleg1973 1.9.2005, 22:03
пардон может я не так понял
но чем lstrcpy не устраивает в данном случае?

Автор: Akina 1.9.2005, 22:51
Цитата(oleg1973 @ 1.9.2005, 23:03)
чем lstrcpy не устраивает в данном случае?

Тем что VB про существование такой функции не знает

Автор: oleg1973 1.9.2005, 23:08
Цитата
Тем что VB про существование такой функции не знает

еше раз пардон
а что разве в ВБ недоступны стандартные АПИ функции винды?

п.с.
я просто на ВБ ни разу ни того smile

Автор: __Sergey__ 1.9.2005, 23:45
так я не понял, как на счет байтового массива?
с ReadFile работает без проблем.
показал бы код и какие ошибки вылазят, а то разговор уходит в
неизвестное направление smile

Цитата(Kergan @ 1.9.2005, 16:23)
для тех кто не в курсе char* - почти строка, это указатель на нулевой символ

char* - не почти строкаsmile и не указатель на нулевой символ, а указатель на строку, заканчивающуюся нулевым байтом.
можно так же сказать, что это указатель на первый символ строки.
таким способом: "byref buff as string", ты передаеш адрес BSTR(т.е. указатель на массив символов в юникоде), тогда
как твоя ф-ция на сях ждет АBSTR - указатель на массив ANSI символов.

Автор: Akina 2.9.2005, 08:29
Цитата(__Sergey__ @ 2.9.2005, 00:45)
как на счет байтового массива? с ReadFile работает без проблем.

Байтовый массив не устраивает - нужно получать именно стринг, для последующей строковой обработки. А пережевывать байтовый массив в строку - долго.
Цитата(oleg1973 @ 2.9.2005, 00:08)
разве в ВБ недоступны стандартные АПИ функции винды?

Почему? доступны... только что и куда ты предлагаешь копировать?

Автор: __Sergey__ 2.9.2005, 13:15
Цитата(Akina @ 2.9.2005, 08:29)
нужно получать именно стринг

выдели буфер с помощью String$.
так тоже работает.

Автор: Kergan 2.9.2005, 16:38
Код

Function ReadFromStdInput(Optional ByVal NumBytes As Long = -1) As String
    Dim hStdIn As Long
    Dim ret As Long
    Dim buffer As String
    Dim bytesRead As Long
    hStdIn = GetStdHandle(STD_INPUT_HANDLE)
    buffer = Space$(1024)
    Do
        ret = ReadFile(hStdIn, ByVal buffer, Len(buffer), bytesRead, ByVal 0&)
        If ret = 0 Then
            Err.Raise 1001, , "Unable to read from standard input"
        End If
        ReadFromStdInput = ReadFromStdInput & Left$(buffer, bytesRead)
    Loop Until bytesRead < Len(buffer)
        
End Function

Это РАБОЧИЙ код.
Строка ВСЕГДА передается внешним функциям Byval! Че б там не было написано! ЕЕ имя УЖЕ указатель - на 0-й символ. smile
Пример брал с
http://www.devx.com/vb2themax/Tip/19069

Автор: Mephisto 6.9.2005, 09:56
Цитата(Akina @ 2.9.2005, 08:29)
А пережевывать байтовый массив в строку - долго.

???????
rtlMoveMemory!!!!!
Почему же долго?


Автор: Akina 6.9.2005, 10:15
Цитата(Mephisto @ 6.9.2005, 10:56)
rtlMoveMemory!!!!!
Почему же долго?

Да по той же самой причине - ну избавился я от передачи строки в ReadFile... а в rtlMoveMemory опять-таки надо передавать строковый буфер.

Автор: Kergan 9.9.2005, 16:14
Пардон, Я че-то не секу, а чем вам не нравится использование функции readfile ВООООН в том примере повыше??? Там ведь буффер нормально передается, строкой???

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)