Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.22;
Скачать: CL | DM;

Вниз

Передача строк в/из функции dll   Найти похожие ветки 

 
Aldor_   (2004-08-06 15:41) [0]

В функцию из одной из стандартных библиотек windows в качестве выходного параметра должна передаваться структура, содержащая указатели на строки.
 В описании параметра написано слелующее:
Strings returned by InternetQueryOption are globally allocated, so the calling application must free them when it is finished using them.
 Это что же получается, ОН(она) память выделяет, а Я должен ее освобождать?!
 Что означает globally allocated?
 Под саму структуру (в том числе и указатели на строки) память выделять и освобождать мне?
 И что передавать в качестве размера буфера?


 
TUser ©   (2004-08-06 15:59) [1]

В WinAPI-функции обычно передается PChar (точнее - PAnsiChar). Я тут на форуме недавно с этим разбирался. Если ф-ция должна вернуть что-то в этот буфер, то память надо выделить (размер буфера - максимальный по твоим представлениям размер результата), а потом освободить. Если же ты передаешь строку в апи-функцию (как, например, в FindWindow), то синтаксис такойже, как при работе с обычными строками, а за выделением/освобождением памяти следит компилятор (точнее - менеджер памяти).


 
VMcL ©   (2004-08-06 16:10) [2]

>>Aldor_  (06.08.04 15:41)

GlobalFree(), я полагаю.


 
Aldor_   (2004-08-06 16:12) [3]

TUser ©   (06.08.04 15:59) [1]

 Пробовал делать так:


(* TInternetProxyInfo = record
    dwAccessType: DWORD;
    lpszProxy: LPCSTR;
    lpszProxyBypass: LPCSTR;
  end; *)
const
 MaxStrSize: Cardinal = 1024;
var
 ProxyInfo: PInternetProxyInfo;
 StructSize: Cardinal;
begin
 StructSize := SizeOf(TInternetProxyInfo);
 GetMem(ProxyInfo, StructSize);
 try
   GetMem(ProxyInfo^.lpszProxy, MaxStrSize);
   try
     Inc(StructSize, MaxStrSize);
     InternetQueryOption(nil, INTERNET_OPTION_PROXY, ProxyInfo, StructSize);
   finally
     FreeMem(ProxyInfo^.lpszProxy);
   end;
   ShowMessage(ProxyInfo^.lpszProxy);
 finally
   FreeMem(ProxyInfo);
 end;


На выделенной строке значение ProxyInfo^.lpszProxy МЕНЯЕТСЯ! То есть функция сама присваевает этим указателям какие-то значения, а значит и сама выделят пямять под строки.

 P.S. Естественно, на FreeMem(ProxyInfo^.lpszProxy); вылетает AV


 
VMcL ©   (2004-08-06 16:12) [4]

>>VMcL ©  (06.08.04 16:10) [2]

Хотя нет. Обманул. Вот пример из MSDN:

DWORD dwSize;

// This call determines the buffer size needed.
InternetQueryOption(NULL,INTERNET_OPTION_USER_AGENT,NULL,&dwSize);

// Allocate the necessary memory.
lpszData = new char[dwSize];

// Call InternetQueryOption again with the buffer provided.
InternetQueryOption(NULL, INTERNET_OPTION_USER_AGENT,lpszData,&dwSize);

// Insert code to user the user agent string information.

// Free the allocated memory.
delete [] lpszData;


В общем, сам буфер выделяешь, сам и освобождаешь.


 
Aldor_   (2004-08-06 16:15) [5]

VMcL ©   (06.08.04 16:10) [2]
> GlobalFree(), я полагаю.

Там параметром стоит:
HGLOBAL hMem
[in] Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

 Функция InternetQueryOption этот HGLOBAL не возвращает.


 
VMcL ©   (2004-08-06 16:18) [6]

Надо же. И всё таки я был прав в [2].

Retrieving Connection Options

Beginning with Internet Explorer 5, Internet options can be retrieved from a specific connection. To retrieve options from a particular connection, complete the following steps:

Create a INTERNET_PER_CONN_OPTION_LIST structure.
Allocate the memory for the individual Internet options that you want to retrieve from the connection.
Specify the options using INTERNET_PER_CONN_OPTION structures.
Retrieve the options using InternetQueryOption.
Utilize the option information.
Free the memory that was allocated to hold the option information using the GlobalFree function.


 
VMcL ©   (2004-08-06 16:19) [7]

>>Aldor_  (06.08.04 16:15) [5]

Приведение типов отменили?


 
Aldor_   (2004-08-06 16:19) [8]

VMcL ©   (06.08.04 16:12) [4]
InternetQueryOption(NULL,INTERNET_OPTION_USER_AGENT,NULL,&dwSize);

Функция с ЭТИМ параметром возвращает всего лишь строку, а с INTERNET_OPTION_PROXY возвразает структуру TInternetProxyInfo (описана в [3])

Кстати, вы где примерчик взяли? Я там не нашел...


 
Aldor_   (2004-08-06 16:26) [9]

VMcL ©   (06.08.04 16:19) [7]

 Пока один отвечает, другой уже запостить успевает :)

[6]:

 Да, читал но не разобрался, понял вот так:

 Память под структуру выделяю и освобождаю сам (GetMem/FreeMem)
 Память под строки выделяет функция, но освобождаю я сам с помощью GlobalFree(HGLOBAL(PointerToString))

 Правильно?


 
VMcL ©   (2004-08-06 16:35) [10]

>>Aldor_  (06.08.04 16:26) [9]

>Правильно?

А Гейтс его знает. Почитай в справке. Там примеры есть. А вообще, как любит говорить Игорь Шевченко, "практика - критерий истины".


 
Aldor_   (2004-08-06 16:43) [11]

Спасибо за помощь!


 
Aldor_   (2004-08-07 15:11) [12]

Провел маленькое исследование.
Если вызывать функцию в таком виде:
InternetQueryOption(nil, INTERNET_OPTION_PROXY, ProxyInfo, StructSize); Строка (ProxyInfo^.lpszProxy) пишется по адресу ProxyInfo + SizeOf(TInternetProxyInfo), т.е. внагляк сразу после структуры по стеку.
Освободить память при помощи GlobalFree(HGLOBAL(ProxyInfo^.lpszProxy)) не получилось, как и следовало ожидать, это некорретное преобразование.
Работающим (но не факт что корректным) вариантом оказался такой:

 StructSize := SizeOf(TInternetProxyInfo) + MaxStrSize;
 GetMem(ProxyInfo, StructSize);
 try
   if not InternetQueryOption(nil, INTERNET_OPTION_PROXY, ProxyInfo, StructSize) then
     RaiseLastOSError;
   ShowMessage(ProxyInfo^.lpszProxy);
 finally
   FreeMem(ProxyInfo);
 end;

Таким образом избавляемся от "локальных" накладок, но, возможно, "глобально" эта память все еще считается занятой.

 Буду благодарен, если кто подскажет корректный вариант глобального освобождения памяти.


 
VMcL ©   (2004-08-08 12:11) [13]

>>Aldor_  (07.08.04 15:11) [12]

>Таким образом избавляемся от "локальных" накладок, но, возможно, "глобально" эта память все еще считается занятой.

Не считается. Если посмотришь в Watch, то ProxyInfo^.lpszProxy указывает как раз на область памяти сразу за структурой INTERNET_PROXY_INFO, которую ты предусмотрительно резеревируешь с помощью MaxStrSize. Только, чтобы не "угадывать" MaxStrSize, следует писать так:

procedure TForm1.Button1Click(Sender: TObject);
var
 StructSize: DWORD;
 ProxyInfo: PInternetProxyInfo;
begin
 StructSize := 0;
 if not InternetQueryOption(nil, INTERNET_OPTION_PROXY, nil, StructSize) then
   if GetLastError <> ERROR_INSUFFICIENT_BUFFER then RaiseLastOSError;

 GetMem(ProxyInfo, StructSize);
 try
   if not InternetQueryOption(nil, INTERNET_OPTION_PROXY, ProxyInfo, StructSize) then
     RaiseLastOSError;
   ShowMessage(ProxyInfo^.lpszProxy);
 finally
   FreeMem(ProxyInfo);
 end;
end;


 
Aldor.   (2004-08-08 15:09) [14]

VMcL ©   (08.08.04 12:11) [13]
> ProxyInfo^.lpszProxy указывает как раз на область памяти сразу за структурой INTERNET_PROXY_INFO

 Почему это является признаком того, что память не считается занятой "глобально"?

> Только, чтобы не "угадывать" MaxStrSize, следует писать так:

Угу, так точно, то был черновой вариант.


 
VMcL ©   (2004-08-08 16:56) [15]

>>Aldor.  (08.08.04 15:09) [14]

>Почему это является признаком того, что память не считается занятой "глобально"?

Потому что ты сам её выделил GetMem"ом.



Страницы: 1 вся ветка

Текущий архив: 2004.08.22;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.031 c
3-1091388558
Начинающий
2004-08-01 23:29
2004.08.22


14-1090840675
X9
2004-07-26 15:17
2004.08.22
I can not find KPPP


1-1091773282
Jiuraasdasd
2004-08-06 10:21
2004.08.22
Как наладить переключеник клавишей Tab по текстовым полям?


14-1091449022
Ven
2004-08-02 16:17
2004.08.22
Запуск DOS-овской программы под WinXP


14-1090881129
g-l-u-k
2004-07-27 02:32
2004.08.22
Как скомпилить *.exe





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский