Про плагины, перевод с VC и ошибку access violations

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
krobab
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 08.06.2003 (Вс) 5:34

Про плагины, перевод с VC и ошибку access violations

Сообщение krobab » 13.01.2009 (Вт) 20:01

Здравствуйте.
Пишу плагин для "The Bat" и столкнулся с проблемой перевода с VC, работой функций и памятью в native dll.
1.
На VC она выглядит так:

Код: Выделить всё
int WINAPI TBP_GetName(char* ABuf, int ABufSize)
{
MessageBox(NULL,  ABuf, "TBP_GetName", MB_OK);
   return (getstr(strName, ABuf, ABufSize));
}


Эта функция передаёт название плагина и размер строки в байтах.
getstr - функция копирования строки, в ней используется strncpy.
Как будет правильно выглядеть эта функция на VB и есть-ли strncpy на VB?

2. В моём варианте перевода этой функции постоянно вылетает ошибка access violations at address in "ntdll"(oleaut) read address(write adress), при этом невозможно даже обратиться к переменной, так же вылетает с ошибкой. Что Я делаю не так?
Ошибки появляются если Я пытаюсь копировать или прочитать данные с этих переменных, даже при простой попытке узнать длину переменной через Len() (когда они объявлены как ByRef).
Думал что char* передаётся как указатель, хотя судя по PB он передаётся как указатель, он либо выдаёт ошибку либо выдаёт 0. Пробовал переписывать на PB, такие же ошибки.
Мой вариант перевода этой функции.
Код: Выделить всё
Function TBP_GetName(ByVal ABuf As Long, ByVal ABufSize As Long) As Long
    dim sstr As String,hstr As Long
    Dim  llng As Long

    sstr = "TEST"
    hstr = StrPtr(sstr)
    llng = ABufSize

    MessageBox 0, SysAllocString(ABuf) & Str(llng), "TBP_GetName", 0

End Function

Проверял на Total Commander, написал для него тестовый плагин, все переменные читаются и изменяются без ошибок.

3. Как правильно объявить SysAllocString, SysAllocStringLen и SysAllocStringByteLen? В APIviewer, который с AllAPI.net объявления почему-то as Byte и при вызове вылетает ошибка overflow, с SysAllocString Я разобрался, а остальные всёрано выдают ошибку.

4. Немного ламерский вопрос, как в copymemory да и вообще в API функциях правильно расставлять byval, или где про это можно прочитать?

P.S.
Читал статьи и ответы на некоторые темы, что-то помогло, где-то пока не разобрался ещё.
Пользуюсь "компилятором native DLL" от Хакера, единственный, который нормально создаёт такие библиотеки.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Про плагины, перевод с VC и ошибку access violations

Сообщение Хакер » 13.01.2009 (Вт) 20:21

1. Чтобы ответить на вопрос, мне нужно иметь спецификацию по TBP_GetName. Что в неё приходит и что она должна отдавать. По твоему варианту не понятно.

2. Этот пункт является продолжением п.1.
3. Как в MSDN, с учетом типов VB. Точнее — в зависимости от целей использования.
4. Так же, как и не в API, а в обычных. Прочитать в справке к VB, хотя это один из тех моментов, который должен быть понятен без справки по одному только названию.

Пользуюсь "компилятором native DLL" от Хакера, единственный, который нормально создаёт такие библиотеки.

Спасибо. Этот продукт называется Fire Native DLL (или сокращённо FNDLL).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

krobab
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 08.06.2003 (Вс) 5:34

Re: Про плагины, перевод с VC и ошибку access violations

Сообщение krobab » 13.01.2009 (Вт) 21:08

Спасибо, нашёл свою ошибку, которую незаметил, точнее поленился заметить и это при том, что был даже пример плагина пустышки.
1.
Вот спецификация.
http://www.nobat.ru/api/plug_api.html

Синтаксис:
С++
int WINAPI TBP_GetName(char* ABuf, int ABufSize);

Описание:
Данная функция вызывается, чтобы получить имя плагина.

Параметры:

ABuf
[out]
Указатель на буфер, принимающий строку с именем плагина. Если ABuf является нулевым указателем, то функция должна вернуть значение, равное необходимому размеру буфера в байтах.

ABufSize
[in]
Размер строкового буфера, на который указывает ABuf, в байтах. Если ABufSize отрицательно, функция должна вернуть значение, равное необходимому размеру буфера в байтах.

Положительное число
Число байт, записанных в ABuf или необходимый размер буфера.

Нуль или
отрицательное число
Функция не поддерживается.

Вот нормальный перевод этой функции.

Код: Выделить всё
Function TBP_GetName(ByVal ABuf As Long, ByVal ABufSize As Long) As Long
    Dim sstr As String
    Dim hstr As Long, llng As Long
     sstr = StrConv("TEST PLUGIN", vbFromUnicode)
    hstr = StrPtr(sstr)
    If ABuf = 0 Then
        TBP_GetName = LenB(sstr)
    Else
        CopyMemory ByVal ABuf, ByVal hstr, ABufSize
        TBP_GetName = LenB(sstr)
    End If
    MessageBox 0, Str$(ABuf) & Str$(ABufSize), "TBP_GetName", 0
End Function


2. и 3. Всё время забываю про MSDNS и Хелп, будем смотреть.

P.S. Спасибо, что направляете нас на путь истинный +).
P.P.S. Нашёл ещё очередную ошибку после того как ответил на вопрос. Всё работает прекрасно! Спасибо.
Последний раз редактировалось krobab 13.01.2009 (Вт) 21:25, всего редактировалось 1 раз.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Про плагины, перевод с VC и ошибку access violations

Сообщение Хакер » 13.01.2009 (Вт) 21:23

Перевод кривой, и в целом неправильный.

1) Строку TBP_GetName = Len(sstr) вынеси из if-endif-блока.
2) Непонятно, какую строку хочет получить вызывающая сторона — null-терминированную или нет. Если Null-терминированную, то надо возвращать Len(sstr) + 1
3) По адресу, содержащемуся в hstr хранится адрес юникодной строки "QQQ". Вызывающая сторона явно (судя по сишному прототипу и описанию) ожидает ANSI-шную строку.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Про плагины, перевод с VC и ошибку access violations

Сообщение tyomitch » 13.01.2009 (Вт) 21:31

3, 4: зависит от контекста использования; нет "единственно правильных" объявлений.
Изображение

krobab
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 08.06.2003 (Вс) 5:34

Re: Про плагины, перевод с VC и ошибку access violations

Сообщение krobab » 13.01.2009 (Вт) 21:39

Спасибо Хакер.
1. TBP_GetName - это Я для себя так пишу, чтобы быстрей разобраться, потом это всё убирается.
2. Строка не должна содержать завершающего нулевого символа, пункт 3.3..
3. Да там ANSI, до Вашего ответа Я нашёл эту и другую ошибку.

А теперь перевод нормальный :roll: ?

Код: Выделить всё
Function TBP_GetName(ByVal ABuf As Long, ByVal ABufSize As Long) As Long
    Dim sstr As String, hstr As Long
    sstr = StrConv("TEST PLUGIN", vbFromUnicode)
    hstr = StrPtr(sstr)
    TBP_GetName = LenB(sstr)
    If ABuf <> 0 Then CopyMemory ByVal ABuf, ByVal hstr, ABufSize
    MessageBox 0, Str$(ABuf) & Str$(ABufSize), "TBP_GetName", 0
End Function


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: SemrushBot, Yandex-бот и гости: 59

    TopList