Vi, нет, он о другом спрашивает.
В Declare при объявлении указание аргументу типа String всегда означает тип AnsiString, и VB всегда будет переводить BSTR (который используется непосредственно самим VB5/VB6/VBA для работу со строками, равно как и всем COM-ом) в LPSTR с помощью WideCharToMultiByte. Более того, после возврата строка будет переведена обратно в BSTR с помощью MultuByteToWideChar.
В любом случае, Declare никак не даёт отказаться от конвертации Unicode→Ansi до вызова, и обратного Ansi→Unicode после вызова.
А вот TLB дают возможность влиять на то, будет ли какое-то преобразование, или нет. У нас в распоряжении три типа: LPSTR, LPWSTR и BSTR.
Для примера вот такая библиотека:
- Код: Выделить всё
library TestOfTypes
{
[dllname("msvbvm60")]
module DummyContainer
{
[entry("VarPtr")] void DummyLPSTR(LPSTR param);
[entry("VarPtr")] void DummyLPWSTR(LPWSTR param);
[entry("VarPtr")] void DummyBstr(BSTR param);
}
}
И вот такой VB код:
- Код: Выделить всё
Public Sub Main()
Test "hello world"
End Sub
Public Sub Test(ByRef s As String)
DummyLPSTR s
DummyLPWSTR s
DummyBstr s
End Sub
В первом случае VB сделает пару конвертацией, обрамив вызов VarPtr (обозванную как DummyLPSTR) парой вызовов
__vbaStrToAnsi (до вызова VarPtr) и
__vbaStrToUnicode (после вызова VarPtr). Во втором и третьем случае никаких конвертаций не будет, оба раза в VarPtr будет передан один и тот же указатель на оригинальную юникодную строку. Таким образом разницы между LPWSTR и BSTR нет, но есть разница между LPWSTR и LPSTR. При LPWSTR и BSTR конвертации туда-сюда нет, при LPSTR — конвертация есть.