конвертация массива байт в строку

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

mshak
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 29.01.2008 (Вт) 14:17

конвертация массива байт в строку

Сообщение mshak » 16.03.2011 (Ср) 17:45

Добрый день.
Имеется несколько сторонних компонентов, первый возвращает бинарный массив - файл загруженный через
Код: Выделить всё
My.Computer.FileSystem.ReadAllBytes(FilePath)

второй компонент - COM компонент, в одной из функций которого входящим параметром является BSTR.
подскажите пожалуйста как правильно реализовать конвертацию массива байт в BSTR на vb.net?

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: конвертация массива байт в строку

Сообщение FireFenix » 16.03.2011 (Ср) 21:03

Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

mshak
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 29.01.2008 (Вт) 14:17

Re: конвертация массива байт в строку

Сообщение mshak » 17.03.2011 (Чт) 12:08

спасибо, но это немного не то.
меня интересует функция аналогичная CAPICOM.Utilities.ByteArrayToStr
можно конечно и ее использовать, но совсем не хочется еще тащить с собой референс к капикому, а написать аналог не знаю как.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: конвертация массива байт в строку

Сообщение FireFenix » 17.03.2011 (Чт) 19:39

Не знаю, что делает функция в твоём классе, но чем не устроила стандартная, что я дал?
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

mshak
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 29.01.2008 (Вт) 14:17

Re: конвертация массива байт в строку

Сообщение mshak » 17.03.2011 (Чт) 22:46

Я просто сравнил результаты их работы.
Допустим есть файл test.bin с неким содержимым и размером 9 байт.
проверяем следующим кодом:
Код: Выделить всё
' ..................
    Public Function ByteArrayToStr(ByVal dBytes() As Byte, ByVal enc As System.Text.Encoding) As String
        Return enc.GetString(dBytes)
    End Function
' ..................
    Public Sub Test_B_BStr()
      ' определение переменных
        Dim ByteArr() As Byte
        Dim CAPIUtil As New CAPICOM.Utilities
        Dim CAPIStr As String = vbNullString
        Dim StrASCII As String = vbNullString
        Dim StrUnicod As String = vbNullString
        Dim StrUTF7 As String = vbNullString
        Dim StrUTF8 As String = vbNullString
        Dim StrUTF32 As String = vbNullString

      'загружаем и преобразуем
      ByteArr = My.Computer.FileSystem.ReadAllBytes("d:\test.bin")
      CAPIStr = CAPIUtil.ByteArrayToBinaryString(ByteArr)
      StrASCII = ByteArrayToStr(ByteArr, System.Text.Encoding.ASCII)
      StrUnicod = ByteArrayToStr(ByteArr, System.Text.Encoding.Unicode)
      StrUTF7 = ByteArrayToStr(ByteArr, System.Text.Encoding.UTF7)
      StrUTF8 = ByteArrayToStr(ByteArr, System.Text.Encoding.UTF8)
      StrUTF32 = ByteArrayToStr(ByteArr, System.Text.Encoding.UTF32)   
    End Sub

в самом конце поставил брекпоинт и смотрел что в строках и их длину (скриншот). Самом похожим оказалось <b>System.Text.Encoding.Unicode</b>.
хотя наверно с предыдущим постом поторопился. буду копать в сторону System.Text.Encoding.Unicode за минусом последнего символа.
Вложения
watch.PNG
скриншот

mshak
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 29.01.2008 (Вт) 14:17

Re: конвертация массива байт в строку

Сообщение mshak » 18.03.2011 (Пт) 14:46

в общем как я понял корректным получается только случай если количество байт в исходном файле четное, иначе непонятки с последним байтом.
видимо все таки прийдется тащить с собой капиком

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: конвертация массива байт в строку

Сообщение iGrok » 18.03.2011 (Пт) 15:12

Эээ..
Так что ж ты хочешь, если подсовываешь функции заведомо неверные данные?
В данном конкретном случае, твой капиком просто обрезал символ, которого не должно быть в строке, а стандартная функция его выдала вместе с остальными, только остальные преобразовала "как надо", а этот - нет.

BSTR предполагает, что все символы кодируются двумя байтами (ибо это строка юникодных символов, если ещё точнее, символов, в кодировке UCS-2). Соответственно, количество байт в корректных входных данных всегда будет чётным.
label:
cli
jmp label

Werebear
Начинающий
Начинающий
 
Сообщения: 2
Зарегистрирован: 18.03.2011 (Пт) 17:39

Re: конвертация массива байт в строку

Сообщение Werebear » 18.03.2011 (Пт) 18:49

Функция SysAllocStringByteLen() создаёт BSTR по ANSI-строке без перекодировки.

Поправил код 26.03.2011.

Код: Выделить всё
#include <windows.h>
#include <stdio.h>

int main()
{
  // Создаём массив из русских однобайтовых ANSI-символов. Восклицательный знак в конце стоит вместо
  // возможного нуля из стека.

  char input[] = {'Т', 'е', 'с', 'т', 'ы', '!'};

  // Инициализируем бинарно-упакованную BSTR массивом ANSI-символов *нечётной* длины.

  BSTR bStr = SysAllocStringByteLen(input, sizeof input - 1);

  // Стандартным образом определяем длину бинарно-упакованной строки.

  UINT bStrByteLen = SysStringByteLen(bStr);

  // Для вывода русских символов на консоль перекодируем BSTR в OEM-кодировку,
  // рассматривая её как массив ANSI-символов.

  char output[sizeof input] = {'\0'};
  CharToOemBuffA((char*)bStr, output, sizeof input - 1);

  // Выводим длину BSTR в символах и в байтах. Показываем, что длина BSTR *в байтах* хранится
  // перед первым символом. Печатаем строку.

  printf("%d %d %u %s\n", SysStringLen(bStr), bStrByteLen, *((unsigned int*)bStr - 1), output);

  // Освобождаем строку.

  SysFreeString(bStr);
}


Результат: 2 5 5 Тесты

Ему нужно вызвать эту функцию из .NET, передав указатель на массив байт и получив IntPtr, а не String, а потом передать полученный указатель в нужный ему метод COM-интерфейса, принимающий BSTR. Первое видимо можно сделать при описании функции с помощью атрибутов, а вот как сделать второе моих знаний .NET не хватает, помогите.

В Капикоме функция ByteArrayToBinaryString() нужна была для подписи бинарных данных из VBScript, который не умеет работать с массивами байт. Например для подписи ANSI-строки в ASP она сначала конвертировалась с помощью функции, подобной StrToBin(), а потом уже подписывалась.

Код: Выделить всё
function StrToBin(ByRef strMsg)

  dim i, binMsg
  for i = 1 to len(strMsg)
    binMsg = binMsg & ChrB(Asc(Mid(strMsg, i, 1)))
  next
 
  StrToBin = binMsg

end function
Последний раз редактировалось Werebear 26.03.2011 (Сб) 13:32, всего редактировалось 1 раз.

Werebear
Начинающий
Начинающий
 
Сообщения: 2
Зарегистрирован: 18.03.2011 (Пт) 17:39

Re: конвертация массива байт в строку

Сообщение Werebear » 21.03.2011 (Пн) 14:48

Решение описывается в этой статье: http://blogs.msdn.com/b/alejacma/archive/2008/08/04/how-to-modify-an-interop-assembly-to-change-the-return-type-of-a-method-_2800_vb.net_2900_.aspx. Сборка-обёртка, автоматически созданная вокруг COM-объекта, дизассемблируется, в описании методов корректируются типы параметров и компилируется обратно в DLL.


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21

    TopList