· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Получить строку из функции

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Авг 17, 2003 05:52:06

Нужно что бы функция внутри библиотеки возвращала строковую переменную в вызывающую её программу.
Как на MASM32 описать следующий алгоритм.

MyMail="Name@Domain.Com"
Переменная=MailMe
MailMe proc
MailMe=MyMail
MailMe endp

Что писать в самой функции и если должен быть параметр, то какого типа.
Какой должен быть синтаксис в программе, вызывающей библиотеку?

Я тут глянул Win32API объявления и обнаружил что Виндовые функции не возвращают строчных переменных. Всё идёт через массивы байт в параметрах или структурных параметрах.

Пожалуйста примерчик, если можно.

Спасибо.


Дата: Авг 17, 2003 06:21:06

Виндовые функции не возвращают строчных переменных.
Это справедливо для большинства сишных функций (исключением можно считать только OLE-COM, который практически заделан под бейсик). Дело в том, что строковые константы рациональней всего передавать через указатель. Защитники OOP могут повозникать, но вы их не слушайте :-)

Пожалуйста примерчик, если можно.
Можно:
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
MailMe PROTO
.DATA
MyMail db "Name@Domain.Com",0
.CODE
DllEntry PROC hInstance:DWORD,reason:DWORD,resvd:DWORD
 mov eax,1
 ret
DllEntry ENDP

MailMe PROC
 mov eax,OFFSET MyMail
 ret
MailMe ENDP

END DllEntry
Потом создаёте DEF, компилите и линкуете DLL...


Дата: Авг 17, 2003 06:49:10

Спасибо, это понятно.
Допустим я передал адрес строчного массива.
Не могли бы вы подсказать как бы теперь его принять.
Можно и для C++ и для Vb
Если на ЯВУ я не могу его принять, то может быть как то через параметр?


Дата: Авг 17, 2003 08:49:05

Я имел ввиду последнюю часть своего вопроса:
>Какой должен быть синтаксис в программе, вызывающей библиотеку?
Допустим я получил указатель на адрес.
Как теперь из адреса получить массив байт.
Может
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
У меня правда ничего не получилось.

Числа у меня нормально получается принять, а вот строки никак. Может всё таки возврат строчной функции нужно возвращать не через EAX?

Может я чего недопонимаю? Ведь это простейшая операция. Так не ругайте сильно чайника - просто обясните.


Дата: Авг 17, 2003 09:13:55

Допустим я получил указатель на адрес.
Указатель -- это и есть адрес.

Ведь это простейшая операция.
Действительно. Под VC можно так:
// Прототип:
extern "C" LPTSTR __stdcall MailMe(void);
// . . .
char strBuf[128];
lstrcpy(strBuf,MailMe());

ЗЫ: Не забудьте добавить LIB от DLL.


Дата: Авг 18, 2003 05:10:43

Всё, спасибо народ, я разобрался.
Извините за бабуиновский язык, но я к нему привык ещё со Спектрума :)

Private Declare Function PointerFromDLL Lib "BP-DLL1.dll" Alias "MailMe" () As Long

hLib = LoadLibrary(App.Path & "\BP-DLL1.dll")

On Error Resume Next
Dim AnsiString(0 To 255) As Byte
CopyMemory AnsiString(0), ByVal PointerFromDLL, 255&
MyMail = StrConv(AnsiString, vbUnicode)
MyMail = Left(MyMail, InStr(1, MyMail, Chr(0)) - 1)
MsgBox MyMail, , Len(MyMail)

FreeLibrary hLib

Спасибо Quantum. Я тоже сначала хотел использовать offset, но потом чего то испугался и попытался использовать инструкцию addr. Насколько я понял, она применима только к макрокоманде Invoke.

Но тут сразу же возникает другой вопрос!
Как мне найти длину строки, полученной из библиотеки.
Я от фонаря скопировал в байтовый массив 255 байт с адреса,
полученного из функции.
А если длина передаваемой строки больше?
Как мне передать (или узнать в приёмнике) сколько бат
находится в памяти по указаному адресу.
Если копировать по одному байту до кода 0, то VB получится, мягко говоря, несколько долго.
Может какие регистры должны быть переключены, что бы автомат VB знал количество байт. Я в регистрах не очень разбираюсь. Звиняйте уж ламера.

Ещё раз Спасибо.

PS: Кстати, люди, я не нашёл на вашем сайте описания регистров. Может плохо искал?


Дата: Авг 18, 2003 06:43:24

Я тоже сначала хотел использовать offset, но потом чего то испугался и попытался использовать инструкцию addr. Насколько я понял, она применима только к макрокоманде Invoke.
"addr lable" в случае с invoke транслируется в:
lea eax,lable
push eax
"offset lable" транслируется просто в:
push XXXX ; (XXXX -- это адрес lable)
Как можете заметить, OFFSET не использует регистр EAX и занимает меньше места. Зато ADDR применима к локальным переменным (которые в стеке). В общем, старайтесь по возможности использовать OFFSET.

Как мне найти длину строки, полученной из библиотеки.
lstrlen -- API ф-ция. На C/C++ можно так:
len = lstrlen(MailMe());

Может какие регистры должны быть переключены, что бы автомат VB знал количество байт.
Нет, к регистрам это не имеет отношения. Кстати, а вы не пробовали возвращать из DLL юникодовую строку, чтоб лишний раз не конвертировать потом из ANSI в юникод?


Дата: Авг 18, 2003 07:23:22

"addr lable" в случае с invoke транслируется в:
lea eax,lable
push eax

Насколько я понял из этого кода addr - это вовсе не инструкция, а опять же макрокоманда. Буду знать :)

Кстати, а вы не пробовали возвращать из DLL юникодовую строку, чтоб лишний раз не конвертировать потом из ANSI в юникод?
Спасибо, очень рациональное предложение. Надо только проверить будет ли работать.
Наверное это должно выглядеть так:
.DATA
MyMail dw "Name@Domain.Com",0
И ещё этот ноль. Имхо, в юникоде он не нужен.

Ещё небольшой вопрос. Передача рисунков может осуществляться тем же способом?


Дата: Авг 18, 2003 11:22:16

И ещё этот ноль. Имхо, в юникоде он не нужен
Это в bstr он не нужен, т.к. там длина строки записана перед самой строкой.


Дата: Авг 18, 2003 11:41:30

CyberRat
В независимости от ответов, посмотрите тему про то, как в ЯВУ передаются параметры. Кстати можно это сделать в Зубкове..
Но сейчас появилась книга Абеля в продаже :)

CyberRat
Это что X86? :) ЭЭЭ, вообще то есть статьи Серржио.
Аааааа, попробуйте найти первое издание Зубкова где то на Netlib.ru

Ещё небольшой вопрос. Передача рисунков может осуществляться тем же способом?

Скажите, а разве РИСУНОК в конце концов это не массив байт? :)


Дата: Авг 19, 2003 04:39:47

Edmond

Извините, не совсем понял что вы от меня хотите.


Дата: Авг 19, 2003 05:07:25

Это что X86? :)
А, понял, это вы про мой вопрос о регистрах.
Дело в том что такие книги расчитаны на людей, уже имеющих специальное образование. В них много мусора и путанницы.
А статьи с вашего сайта доступны для понимания широкому кругу читателей. Вот и хотелось бы что бы изучение языка начиналось не с середины а с начала.
По аналогии есть сайты о ЯВУ, в которых пропущены описания типов данных, но ведь этих сайтов как грибов после дождя. А по MASM32 - раз, два и обчёлся.


Дата: Авг 19, 2003 14:05:25

CyberRat
Ааа. Понял.
Но про регистры кажется есть в статье у Серржио.
(Или это я не про ту статью вспомнил?)


Дата: Авг 21, 2003 07:18:43

Edmond
Если вы имеете ввиду
СТАТЬИ > Низкоуровневое программирование для дZенствующих
То там я нашёл описание только первых 4-х и то очень скудно.


Дата: Авг 21, 2003 15:10:22

CyberRat
Мдя.. Ну ничего. Кстати а почему бы вам в сети не найти Абеля, или купить? Он ест на руссоком от издательства DiaSoft

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.064