powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
6 сообщений из 6, страница 1 из 1
Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
    #37916762
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример кода:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
Private Sub CommandRegister_Click()
    Dim NewMes As OpalMessageRegistration
    Dim BackMesPtr As Long
    Dim MesType As OpalMessageType
    NewMes.m_type = OpalCmdRegistration
    NewMes.m_param.m_protocol = VarPtr(StringToMas("sip").ByteStr(0))
...
    BackMesPtr = OpalSendMessage_Registration(L, NewMes) '<<возвращает IntPtr-указатель еа структуру
    MsgBox BackMesPtr
    If BackMesPtr = 0 Then Exit Sub
    CopyMemory MesType, ByVal BackMesPtr, 4 '<<копируем первый long структуры
    If MesType = OpalIndCommandError Then
        Dim s_CommandError As Long
        CopyMemory s_CommandError, ByVal BackMesPtr + 4, 4 '<<копируем оставшийся long структуры
        MsgBox "Error: " & PtrToString(s_CommandError)
        'OpalFreeMessage '<<в документации Opal сказано что так надо
        Dim MesFreeEr As OpalMessageCommandError
        MesFreeEr.m_type = OpalIndCommandError
        MesFreeEr.m_param = s_CommandError
        OpalFreeMessage_CommandError MesFreeEr
    ElseIf MesType = OpalCmdRegistration Then
        Dim s_Registration As OpalParamRegistration
        CopyMemory ByVal VarPtr(s_Registration), ByVal BackMesPtr + 4, LenB(s_Registration) '<<копируем оставшуюся часть структуры
        MsgBox "m_protocol: " & PtrToString(s_Registration.m_protocol) & vbCrLf & _
          "m_identifier: " & PtrToString(s_Registration.m_identifier) & vbCrLf & _
...
        'OpalFreeMessage '<<в документации Opal сказано что так надо
        Dim MesFree As OpalMessageRegistration
        MesFree.m_type = OpalCmdRegistration
        MesFree.m_param = s_Registration
        OpalFreeMessage_Registration MesFree
    End If



Что неясно.
1. OpalSendMessage_ возвращает указатель BackMesPtr на место A
При использовании CopyMemory я создаю копию в место B
Если я правильно понимаю, то память в место A и место B остается занята.

2. Абсолютно не ясен смысл чего там удаляет в памяти опаловская OpalFreeMessage
Из документации и кодов Opal:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
/** Free memeory in message the OPAL system has sent. The parameter must be
    the message returned by OpalGetMessage() or OpalSendMessage().
  */
void OPAL_EXPORT OpalFreeMessage(OpalMessage * message);
  void OPAL_EXPORT OpalFreeMessage(OpalMessage * message)
  {
    if (message != NULL){
      free(message);
    }
  }
void   __cdecl free(__inout_opt void * _Memory);



В VB6 декларирую так:
Код: vbnet
1.
2.
Public Declare Function OpalFreeMessage_... Lib "opal.dll" Alias "OpalFreeMessage" _
  (ByRef Message As OpalMessage...) As Long



В отличии от OpalSendMessage_
Код: vbnet
1.
2.
Public Declare Function OpalSendMessage_... Lib "opal.dll" Alias "OpalSendMessage" _
  (ByVal opal As Long, ByRef Message As OpalMessage...) As Long



OpalFreeMessage_... даже не содержит хэндла на процесс dll возвращенный при инициализации(ByVal opal As Long),
т.е. не понятно каким боком оно очищает место A (про которое знает Opal) или место B , про кот. Opal не знает(куда я скопировал через CopyMemory).
А ссылаюсь я походу вообще на место C ( Dim MesFree As OpalMessageRegistration)
Хотя подозреваю что место С = место B (операцией присваивания).

Кто нибудь разжует, нужна ли эта OpalFreeMessage? Да и правильно ли я ее применяю в VB6 - сомнения...?
и нужно ли что-то еще?

Или выкинуть OpalFreeMessage и забить на все (на работу не влияет, хотя память еще забьеся - тоже неприятно).
...
Рейтинг: 0 / 0
Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
    #37918088
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так что не разжует никто?

Я обратил внимание, что при вызовах
OpalFreeMessage как я это делаю в приведенном коде
VB-приложение часто ( случайно!!! ) дает crash.
Причем если верить виндам, то Crash обычно связан с попыткой чтения памяти по адресу "0x00...04"
C чего бы это, 4 - длина as Long

Я вообще не уверен
1) Что я вызываю OpalFreeMessage правильно
2) Что она вообще реально нужна.

Я убрал конструкции вида:
Код: vbnet
1.
2.
3.
4.
5.
        'OpalFreeMessage '<<в документации Opal сказано что так надо
        Dim MesFree As OpalMessageRegistration
        MesFree.m_type = OpalCmdRegistration
        MesFree.m_param = s_Registration
        OpalFreeMessage_Registration MesFree


-крашей больше не видно.

Память не сдохнет?
...
Рейтинг: 0 / 0
Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
    #37918210
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Дмитрий77
> Так что не разжует никто?

Дима, это нужно вычитывать в документации к твоему Опалу. Нужно ли делать OpalFreeMessage для полученых сообщений, или
система их сама внутри освобождает после отдачи тебе функцией GetMessage(). Или спрашивать у разработчика.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
    #37918396
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Горбонос,
>Или спрашивать у разработчика.
Да, только разработчик VB6 знает сильно хуже чем я C++ не знает вообще
>в документации >Нужно ли делать OpalFreeMessage

В документации написано что НАДО посылать OpalFreeMessage после каждого OpalGetMessage() or OpalSendMessage().
Судя по документации:
Дмитрий77Из документации и кодов Opal:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
/** Free memeory in message the OPAL system has sent. The parameter must be
    the message returned by OpalGetMessage() or OpalSendMessage().
  */
void OPAL_EXPORT OpalFreeMessage(OpalMessage * message);
  void OPAL_EXPORT OpalFreeMessage(OpalMessage * message)
  {
    if (message != NULL){
      free(message);
    }
  }
void   __cdecl free(__inout_opt void * _Memory);


OpalFreeMessage тупо освобождает память занимаемую исходным message.
free(message);

Но при этом message (на логике C++ и как задумано), передаваемый в OpalFreeMessage суть тот же самый message, полученный в OpalGetMessage() or OpalSendMessage(), занимающий ту же область памяти, что и занимал.

А я вместо того чтоб очищать исходно занятую память,
похоже отправляю команду очистить память занятую КОПИЕЙ (CopyMemory).
Причем походу VB6 сам эту копию уничтожает по выходу из Private Sub CommandRegister_Click().
Код: vbnet
1.
2.
    CopyMemory MesType, ByVal BackMesPtr, 4 '<<копируем первый long структуры
    CopyMemory ByVal VarPtr(s_Registration), ByVal BackMesPtr + 4, LenB(s_Registration) '<<копируем оставшуюся часть структуры



М.б.
1) заменить CopyMemory на MoveMemory (<< это сразу сделает то же самое, что ожидается от OpalFreeMessage и освободит память, которую изначально занимает message)
2) Убрать OpalFreeMessage из VB6 кода, т.к. бессмысленно в силу пункта(1)
3) КОПИЯ автоматически уничтожится встроенными средствами VB6

ТАК? Если не так пожалуйста поправьте.
...
Рейтинг: 0 / 0
Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
    #37918408
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий771) заменить CopyMemory на MoveMemory (<< это сразу сделает то же самое, что ожидается от OpalFreeMessage и освободит память, которую изначально занимает message)
Глупость сказал. Это одно и то же
RtlMoveMemory
Тогда думаю надо просто выкинуть OpalFreeMessage и будет счастие.
...
Рейтинг: 0 / 0
Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
    #37949916
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Горбонос> Автор: Дмитрий77
> Так что не разжует никто?

Дима, это нужно вычитывать в документации к твоему Опалу. Нужно ли делать OpalFreeMessage для полученых сообщений, или
система их сама внутри освобождает после отдачи тебе функцией GetMessage(). Или спрашивать у разработчика.
Ну, разработчик ответил буквально следующее:
РазработчикAll I can say is if you do not use OpalFreeMessage() you will probably leak memory.

Note OpalFreeMessage is only used for messages provided as return value by OpalGetMessage or OpalSendMessage, it is not for messages you create.

Ну т.е. вот так тогда надо???:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
Public Declare Function OpalSendMessage_SetGeneralParameters Lib "opal.dll" Alias "OpalSendMessage" _
  (ByVal opal As Long, ByRef Message As OpalMessageGeneral) As Long 'возвращает Ptr на ответный Message
Public Declare Function OpalFreeMessage Lib "opal.dll" (ByVal ptr As Long) As Long

Private Sub CommandSetGeneral_Click()
    Dim NewMes As OpalMessageGeneral
    Dim BackMesPtr As Long 'сюда принимаем Ptr на ответный Message
    Dim MesType As OpalMessageType
    NewMes.m_type = OpalCmdSetGeneralParameters
    NewMes.m_param.m_audioRecordDevice = VarPtr(StringToMas(ListRecorder.Text).ByteStr(0))
...
    BackMesPtr = OpalSendMessage_SetGeneralParameters(L, NewMes) 'получили Ptr на ответный Message в BackMesPtr
    'сначала разбираемся с BackMesPtr
    TextBoxAdd TextSendMes, "CmdSetGeneralParameters: BackMesPtr=" & BackMesPtr
    If BackMesPtr = 0 Then Exit Sub
    CopyMemory MesType, ByVal BackMesPtr, 4
    If MesType = OpalIndCommandError Then
        Dim s_CommandError As Long
        CopyMemory s_CommandError, ByVal BackMesPtr + 4, 4
        TextBoxAdd TextSendMes, "Error: " & PtrToString(s_CommandError)
    ElseIf MesType = OpalCmdSetGeneralParameters Then
        Dim s_GeneralParameters As OpalParamGeneral
        CopyMemory ByVal VarPtr(s_GeneralParameters), ByVal BackMesPtr + 4, LenB(s_GeneralParameters)
        With s_GeneralParameters
          ...
          'разбор BackMesPtr
        End With
    End If
    'разобравшись даем команду на удаление обратного Message по его указателю BackMesPtr пусть этим занимается Opal
    OpalFreeMessage BackMesPtr
    ...
End Sub


В Opal имеем следующий код по поводу OpalFreeMessage:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  void OPAL_EXPORT OpalFreeMessage(OpalMessage * message)
  {
    if (message != NULL){
      PTRACE(1, "OpalC\tOpalFreeMessage received " << message->m_type);
      free(message);
    }
  }

_CRTIMP                     _CRTNOALIAS     void   __cdecl free(__inout_opt void * _Memory);



Судя по логу Opal когда так делаю,Opal понимает о чем идет речь:
Код: plaintext
1.
  0:00.936	                    vb6	OpalC	OpalFreeMessage received CmdSetGeneralParameters


Смотрим описание функции free
Deallocates or frees a memory block.
The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc).


mallloc вроде как используется при подготовке обратного сообщения на которое указывает BackMesPtr:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
bool OpalContext::SendMessage(const OpalMessagePtr & message, OpalMessagePtr & response)
{
...
    response.SetType(...);

void OpalMessagePtr::SetType(OpalMessageType type)
{
...
  m_message = (OpalMessage *)malloc(sizeof(OpalMessage)); // Use malloc to be compatible with OpalFreeMessage
  memset(m_message, 0, sizeof(OpalMessage));
  m_message->m_type = type;
}



Т.е. логично ли и правдоподобно следующее?
1) Посылаю OpalSendMessage, получаю назад указатель BackMesPtr
2) По указателю BackMesPtr ковыряю память и обрабатываю Message (моим VB6 приложением)
3) Скармливаю указатель BackMesPtr ф-ции OpalFreeMessage Lib "opal.dll" (ByVal ptr As Long) (т.к. уже его обработал)
(Если этого не делаю, теряю память, занимаемую Message)
4) Дальше не мои проблемы и память занимаемая Message освобождается на стороне Opal (т.к. мой указатель известен Opal, ибо был заранее препарирован с помощью malloc и он знает как делать free ).
Так что ли?
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Объясните мне надо ли освобождать память в частности при CopyMemory и как, не догоняю
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]