Re[5]: Способы передачи строк
От: Vi2 Удмуртия http://www.adem.ru
Дата: 23.04.03 06:36
Оценка:
Здравствуйте, ma3ai, Вы писали:

M>Самое главное, о чём я до этого не подозревал это то, что VB фактически хранит 2 (!) строки в разных местах:
M>1 — Однобайтовая (ANSI) строка. Для передачи в API типа FuncA
M>2 — Двухбайтовая (Unicode) строка для себя или для API ф-ий типа FuncW.
M>Проверить можно кодом ниже. Это ж какая расточительность, блин – на каждый символ 3 байта.

На самом деле ты проверил не хранение, а способы передачи строки в подпрограммы. Да, есть 2 способа. Но как хранит строки сам VB — это загадка. Скорее всего в Варианте с VT_BSTR, VT_LPSTR или VT_LPWSTR.

Поэтому, если тебе нужно передавать char*, то описывай параметр как ByVal s As String и передавай s.
Если тебе нужно передавать wchar_t*, то описывай параметр как ByVal s As Any и передавай StrPtr(s).

Private Declare Sub TestVarAnsi Lib "moddll" Alias "_TestVarAnsi@4" (ByVal pDoc As String)
Private Declare Sub TestVarUni Lib "moddll" Alias "_TestVarUni@4" (ByVal pDoc As Any)

Private Sub Form_Load()
  Dim s As String
  s = "abc"
  
  Call TestVarAnsi(s)
  Call TestVarUni(StrPtr(s))
  
  Unload Me
End Sub


__declspec(dllexport) void __stdcall TestVarAnsi(/*[in,out]*/ LPSTR pStatus )
{
    pStatus[1] = 'A';
    return;
}

__declspec(dllexport) void __stdcall TestVarUni(/*[in,out]*/ LPWSTR pStatus)
{
    pStatus[1] = 'B';
    return;
}

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

PS
Работа со строками отличается от других типов особенно в массивах s() As String и i() As Long. i(0) можно передавать в функции как long* и получать доступ ко всем элементам массива. Со строками это не проходит по указанной выше причине — VB манипулирует с ними дополнительно, хотя известно что строки хранятся в массиве как указатели на BSTR.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.