powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
13 сообщений из 13, страница 1 из 1
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913345
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
C# смотрел, ну эт надо учебники штудировать, чтоб на нем чего-то серьезно делать, метод тыка не нравится.
Пытаюсь все-таки осилить Opal API под VB6, проводя аналогию с имеющимся кодом C#.
Чуток продвинулся.

В C# условно (условно, потому что я опустил пока борьбу с union, кот. в C# реализована через [FieldOffset(0)]) имеем:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    public struct OpalParamRegistration
    {
      public IntPtr m_protocol;
      public IntPtr m_identifier;
      public IntPtr m_hostName;
      public IntPtr m_authUserName;
      public IntPtr m_password;
...

    public struct OpalMessage    {
      public OpalMessageType m_type;
      public OpalParamRegistration m_param;
    }

'[DllImport("OPAL.DLL", CallingConvention = CallingConvention.StdCall)]
'public static extern IntPtr OpalSendMessage(IntPtr opal, ref OpalMessage message);

      set { m_param.m_protocol = Marshal.StringToCoTaskMemAnsi(value); }



На VB6 накатал сначала следующее:
Код: 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.
Public Type OpalParamRegistration
  m_protocol As Long  'IntPtr
  m_identifier As Long  'IntPtr
  m_hostName As Long  'IntPtr
  m_authUserName As Long  'IntPtr
  m_password As Long 'IntPtr
...
Public Type OpalMessageRegistration
  m_type As OpalMessageType
  m_param As OpalParamRegistration
End Type

Public Declare Function OpalSendMessageRegistration Lib "opal.dll" Alias "OpalSendMessage" _
  (ByVal opal As Long, ByRef Message As OpalMessageRegistration) As Long

Private Sub CommandRegister_Click()
    Dim NewMes As OpalMessageRegistration
    Dim BackMes As Long
    NewMes.m_type = OpalCmdRegistration
    NewMes.m_param.m_protocol = VarPtr("sip")
    NewMes.m_param.m_identifier = VarPtr("100@192.168.1.3")
    NewMes.m_param.m_password = VarPtr("100")
    BackMes = OpalSendMessageRegistration(L, NewMes)
    MsgBox BackMes



В логе Opal прочитал:
vb6 OpalC API Handling message CmdRegistration from application
vb6 OpalC API Command CmdRegistration error: No such protocol prefix

т.е. NewMes.m_param.m_protocol = VarPtr("sip") слово "sip" передала неправильно

Исправил на
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Public Type OpalParamRegistration
  m_protocol As String  'IntPtr
  m_identifier As Long  'IntPtr
  m_hostName As Long  'IntPtr
  m_authUserName As Long  'IntPtr
  m_password As Long 'IntPtr

    NewMes.m_param.m_protocol = "sip"


-это место типа прошел, лог стал ругаться на hostname и т.д.
Пошел дальше:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public Type OpalParamRegistration
  m_protocol As String  'IntPtr
  m_identifier As String  'IntPtr
  m_hostName As String 'IntPtr
  m_authUserName As String 'IntPtr
  m_password As String 'IntPtr
...
    NewMes.m_type = OpalCmdRegistration
    NewMes.m_param.m_protocol = "sip"
    NewMes.m_param.m_identifier = "100@192.168.1.3"
    NewMes.m_param.m_password = "100"


В логе вижу, что вроде как процесс пошел:
0:03.503 opalvb SIP Constructed REGISTER handler for sip:100@192.168.11.3
0:03.503 opalvb SIP Executing state change to Subscribing for REGISTER handler,

Но VB6 app после этого вызова вылетает...( если в Public Type OpalParamRegistration сделать более одного As String)

Чего-то я не догоняю...какой-то VB6 хитрости.. на чего заменить IntPtr и Marshal.StringToCoTaskMemAnsi(value)?

В оригинале (откуда эта API вызывается)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
typedef struct OpalParamRegistration {
  const char * m_protocol;
  const char * m_identifier;
  const char * m_hostName;
  const char * m_authUserName;
  const char * m_password;
...
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913407
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дмитрий77,
может сделать строки nullterminated?
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913550
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
скукотищаможет сделать строки nullterminated?
Что конкретно имеете в виду?
Если сделать
Код: vbnet
1.
2.
3.
Public Type OpalParamRegistration
  m_protocol As String*255  'IntPtr
  m_identifier As String*255  'IntPtr


то вышибает точно также при попытке передать более одного строкового параметра

Если делать
Код: vbnet
1.
NewMes.m_param.m_protocol = "sip" & vbNullChar


то
vb6 OpalC API Command CmdRegistration error: No such protocol prefix
(в смысле не читает слово "sip" как задумано, при этом от вылета при добавлении второго String/String*255 параметра не спасает)

Я тут вычитал, что String надо передавать как ByVal,
но у меня
Message As OpalMessageRegistration, (можно только ByRef)
а string засунуто в структуры

Мне по идее надо передать указатели на эти String, но с Long + VarPtr/StrPtr ничего не получается (самый верхний VB6 пример)
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913585
скукотища
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дмитрий77,
Код: vbnet
1.
2.
3.
Public Type OpalParamRegistration
  m_protocol As Long
  m_identifier As Long


Код: vbnet
1.
NewMes.m_param.m_protocol = StrPtr("sip" & vbNullChar & vbNullChar)
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913588
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
скукотища
Код: vbnet
1.
2.
3.
Public Type OpalParamRegistration
  m_protocol As Long
  m_identifier As Long


Код: vbnet
1.
NewMes.m_param.m_protocol = StrPtr("sip" & vbNullChar & vbNullChar)


Не работает.
Command CmdRegistration error: No such protocol prefix

По идее типы со String в VB встречаются:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Public Type OPENFILENAME
  nStructSize       As Long
  hwndOwner         As Long
  hInstance         As Long
  sFilter           As String
  sCustomFilter     As String
  nMaxCustFilter    As Long
  nFilterIndex      As Long
  sFile             As String
Public Declare Function GetOpenFileName Lib "comdlg32" _
    Alias "GetOpenFileNameA" _
   (pOpenfilename As OPENFILENAME) As Long



Но отличия:
1. Там оригинал LPCTSTR/LPTSTR,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
typedef struct tagOFN {
  DWORD         lStructSize;
  HWND          hwndOwner;
  HINSTANCE     hInstance;
  LPCTSTR       lpstrFilter;
  LPTSTR        lpstrCustomFilter;
  DWORD         nMaxCustFilter;
  DWORD         nFilterIndex;
  LPTSTR        lpstrFile;



а у меня оригинал const char *
Код: plaintext
1.
2.
 const char * m_protocol;
 const char * m_identifier;



2. Там ByVal (pOpenfilename As OPENFILENAME)
а у меня
ByRef Message As OpalMessageRegistration
и ByVal сделать не дает.
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913593
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я думаю что все-таки VB6 должен передавать Strings, а не указатели.
потому что все as Strings как раз передаются корректно,
но почему-то VB6 вылетает
Дмитрий77
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public Type OpalParamRegistration
  m_protocol As String  'IntPtr
  m_identifier As String  'IntPtr
  m_hostName As String 'IntPtr
  m_authUserName As String 'IntPtr
  m_password As String 'IntPtr
...
    NewMes.m_type = OpalCmdRegistration
    NewMes.m_param.m_protocol = "sip"
    NewMes.m_param.m_identifier = "100@192.168.1.3"
    NewMes.m_param.m_password = "100"


В логе вижу, что вроде как процесс пошел:
0:03.503 opalvb SIP Constructed REGISTER handler for sip:100@192.168.11.3
0:03.503 opalvb SIP Executing state change to Subscribing for REGISTER handler,

Но VB6 app после этого вызова вылетает...( если в Public Type OpalParamRegistration сделать более одного As String)
Т.е. Opal правильно схватил по крайней мере первые 2 стринга.
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913654
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Короче правильно все-таки так (const char *(C++) ==> IntPtr(C#) ==>As String (VB6) ):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public Type OpalParamRegistration
  m_protocol As String 'IntPtr
  m_identifier As String 'IntPtr
  m_hostName As String 'IntPtr
  m_authUserName As String 'IntPtr
  m_password As String 'IntPtr
  m_adminEntity As String 'IntPtr
  m_timeToLive As Long '???
  m_restoreTime As Long '???
  m_eventPackage As String 'IntPtr
End Type



Код
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Private Sub CommandRegister_Click()
    Dim NewMes As OpalMessageRegistration
    Dim BackMes As Long
    NewMes.m_type = OpalCmdRegistration
    
    NewMes.m_param.m_protocol = "sip"
    NewMes.m_param.m_identifier = "100@192.168.1.3"
    NewMes.m_param.m_password = "100"
    NewMes.m_param.m_timeToLive = 300 '<<<<вылетает из-за этой строчки
    BackMes = OpalSendMessageRegistration(L, NewMes)
    MsgBox BackMes
End Sub



вылетает и-за
NewMes.m_param.m_timeToLive = 300
!!! но без этой строчки
'Time in seconds between registration updates. If this is zero then
'the identifier is unregistered
from the server.
'm_timeToLive As Long(вместо register )
UnRegister без m_timeToLive = 300 (=0 по дефолту) Opal судя по логу делает, т.е. API с кучей стрингов срабатывает.
Если уж делать, то надо чтоб все работало!!!

Я не поленился сделать то-же самое на VB.NET через обертку на C# (которую упомянал в соседнем топике)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
    public struct OpalParamRegistration
    {
      public IntPtr m_protocol;
      public IntPtr m_identifier;
      public IntPtr m_hostName;
      public IntPtr m_authUserName;
      public IntPtr m_password;
      public IntPtr m_adminEntity;
      public uint m_timeToLive;
      public uint m_restoreTime;
      public IntPtr m_eventPackage;
    }


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    Private Sub ButtonRegister_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRegister.Click
        Dim NewMes As OpalDotNET.Opal_API.OpalMessage
        Dim BackMes As Long
        NewMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalCmdRegistration
        NewMes.m_param.m_registrationInfo.m_protocol = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("sip")
        NewMes.m_param.m_registrationInfo.m_identifier = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("100@192.168.1.3")
        NewMes.m_param.m_registrationInfo.m_password = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("100")
        NewMes.m_param.m_registrationInfo.m_timeToLive = 300  '<<<<вылетает из-за этой строчки
        BackMes = OpalDotNET.Opal_API.OpalSendMessage(L, NewMes)
        MsgBox(BackMes)
    End Sub


результат такой-же!!!
вылетает и-за этой же строчки:
NewMes.m_param.m_registrationInfo.m_timeToLive = 300
Обертку C# писал не я!!!
В оригинале структура целиком на C++ такая:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
typedef struct OpalParamRegistration {
  const char * m_protocol;      //< Protocol prefix for registration. Currently must be "h323" or
  const char * m_identifier;    //< Identifier for name to be registered at server. If NULL
  const char * m_hostName;      //< Host or domain name for server. For SIP this cannot be NULL.
  const char * m_authUserName;  //< User name for authentication. */
  const char * m_password;      //< Password for authentication with server.
  const char * m_adminEntity;   //< Identification of the administrative entity. For H.323 this will
  unsigned     m_timeToLive;    //< Time in seconds between registration updates. If this is zero then
  unsigned     m_restoreTime;   //< Time in seconds between attempts to restore a registration after
  const char * m_eventPackage;  //< If non-NULL then this indicates that a subscription is made
} OpalParamRegistration;



Т.е. теперь что, с unsigned(C++)/uint(C#)???UInteger(VB.NET)/???Long(VB6) бороться? Идеи есть?
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913780
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
As Long это так:
Код: vbnet
1.
NewMes.m_param.m_registrationInfo.m_timeToLive = 300&
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913786
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>вылетает и-за
>NewMes.m_param.m_timeToLive = 300

Походу с типом вообще все правильно
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public Type OpalParamRegistration
  m_protocol As String 'IntPtr
  m_identifier As String 'IntPtr
  m_hostName As String 'IntPtr
  m_authUserName As String 'IntPtr
  m_password As String 'IntPtr
  m_adminEntity As String 'IntPtr
  m_timeToLive As Long '???
  m_restoreTime As Long '???
  m_eventPackage As String 'IntPtr
End Type


m_timeToLive As Long -число 300 правильно передается.
Разница кажется кроется в том, что API ф-ция OpalSendMessage
Оригинал:
Код: plaintext
1.
OpalMessage * OPAL_EXPORT OpalSendMessage(OpalHandle opal, const OpalMessage * message);


Которую я задекларировал как Long
Код: vbnet
1.
2.
Public Declare Function OpalSendMessageRegistration Lib "opal.dll" Alias "OpalSendMessage" _
  (ByVal opal As Long, ByRef Message As OpalMessageRegistration) As Long


может возвращать ошибку:
The return value is another message which will have a type of
OpalIndCommandError if an error occurs. The OpalMessage::m_commandError field
will contain a string indicating the error that occurred.

И в этом случае As Long "справляется",
а может возвращать такую же навороченную структуру
If successful, the the type of the message is the same as the command type.
А поскольку я все параметры задал правильно, процесс пошел,
и ф-ция возвращает "the the type of the message is the same"
Public Declare Function OpalSendMessageRegistration... As Long
и это As Long приводит к вылету VB6.
Но это надо разбираться дальше.
Хотя странно почему VB.NET тоже вылетает...надо поэкспериментировать.
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37913822
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>вылетает и-за
>NewMes.m_param.m_timeToLive = 300

Короче зря позарился на "новую версию". Сунул тупо более старые версии opal/ptlib (2-х летней давности), даже не убирая "новоявленных" параметров из структур, и с тем же кодом все зарегистрировалось, long вернулся, ни VB6 ни VB.NET не вылетели. Это внутренние проблемы Opal и их исправление выходит за рамки вопроса. Автор как всегда кучу всего улучшает, при этом как всегда куча всего ломается.

Чтож, попробую поизучать API дальше.
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37915148
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77>вылетает и-за
>NewMes.m_param.m_timeToLive = 300

Походу с типом вообще все правильно
Код: vbnet
1.
2.
3.
4.
5.
Public Type OpalParamRegistration
  m_protocol As String 'IntPtr
  m_identifier As String 'IntPtr
  m_hostName As String 'IntPtr
...


Кажется понял еще задницу.
Ф-ция
Код: vbnet
1.
2.
Public Declare Function OpalSendMessageRegistration Lib "opal.dll" Alias "OpalSendMessage" _
  (ByVal opal As Long, ByRef Message As OpalMessageRegistration) As Long


на вход принимает ByRef Message As OpalMessageRegistration
где параметры вложенных структур должны быть As String
А на выходе As Long -это указатель на такой же As OpalMessageRegistration со вложенным OpalParamRegistration,
но предварительные игры с CopyMemory наталкивают на мысль, что возвращаемая структура уже будет с указателями, а не с as String, т.е.
Код: vbnet
1.
2.
3.
4.
5.
Public Type OpalParamRegistration
  m_protocol As Long 'IntPtr
  m_identifier As Long 'IntPtr
  m_hostName As Long 'IntPtr
...



Это что, получается теперь
1) дублировать всю эту иерархию структур для входа/выхода?
2) И на выходе делать сначала CopyMemory чтобы получить структуру в том числе с указателями по указателю на структуру что возвращает ф-ция
3) Потом CopyMemory в String для каждого параметра который суть указатель
Тяжеловато...
Ну на VB.NET рабочий код подобного получился примерно такой:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    Private Sub CommandSetupCall_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CommandSetupCall.Click
        Dim NewMes As OpalDotNET.Opal_API.OpalMessage
        Dim ptrMessage As IntPtr
        Dim BackMes As OpalDotNET.Opal_API.OpalMessage
        NewMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalCmdSetUpCall
        NewMes.m_param.m_callSetUp.m_partyB = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("sip:200@192.168.1.4")
        NewMes.m_param.m_callSetUp.m_callToken = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi(vbNullString)
        ptrMessage = OpalDotNET.Opal_API.OpalSendMessage(L, NewMes)
        If (ptrMessage = IntPtr.Zero) Then
            MsgBox("Invalid message")
        Else
            BackMes = CType(Runtime.InteropServices.Marshal.PtrToStructure(ptrMessage, GetType(OpalDotNET.Opal_API.OpalMessage)), OpalDotNET.Opal_API.OpalMessage)
            If (BackMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalIndCommandError) Then
                MsgBox("Error: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_commandError))
            ElseIf (BackMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalCmdSetUpCall) Then
                MsgBox("m_partyA: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_callSetUp.m_partyA) & vbCrLf & _
                  "m_partyB: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_callSetUp.m_partyB) & vbCrLf & _
                  "m_callToken: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_callSetUp.m_callToken) & vbCrLf & _
                  "m_alertingType: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_callSetUp.m_alertingType) & vbCrLf & _
                  "m_protocolCallId: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_callSetUp.m_protocolCallId))
            End If
        End If
    End Sub


А что будет на VB6, о господи, с расщепленными Union и продублированными на вход/выход структурами...
Чет какая-то фигня... сначала типа для проверки делаю на .NET (которого не знаю), а потом мучительно-извращенно перетаскиваю назад на VB6.
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37915362
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Кажется понял еще задницу.
Ф-ция
Код: vbnet
1.
2.
Public Declare Function OpalSendMessageRegistration Lib "opal.dll" Alias "OpalSendMessage" _
  (ByVal opal As Long, ByRef Message As OpalMessageRegistration) As Long


на вход принимает ByRef Message As OpalMessageRegistration
где параметры вложенных структур должны быть As String
А на выходе As Long -это указатель на такой же As OpalMessageRegistration со вложенным OpalParamRegistration,
но предварительные игры с CopyMemory наталкивают на мысль, что возвращаемая структура уже будет с указателями, а не с as String, т.е.
Это что, получается теперь
...
2) И на выходе делать сначала CopyMemory чтобы получить структуру в том числе с указателями по указателю на структуру что возвращает ф-ция
3) Потом CopyMemory в String для каждого параметра который суть указатель

скукотищаДмитрий77,
Код: vbnet
1.
2.
3.
Public Type OpalParamRegistration
  m_protocol As Long
  m_identifier As Long


Код: vbnet
1.
NewMes.m_param.m_protocol = StrPtr("sip" & vbNullChar & vbNullChar)


То что вы предлагаете передает на вход "s" вместо "sip".
Почему я ХЗ не знаю.

Но то что я решил делать вчера и что вроде как работает, т.е.
"As String"
1) Глючит если структура содержит структуру второго/третьего подуровня, в кот. тоже есть as String.
2) Не имеет обратной совместимости с возвращаемыми структурами с указателями.

Думаю не стоит VB доверять конвертацию String-ов в указатели на них при передаче в API.

Я короче сделал все таки с указателями "на пальцах" (хотя пришлось думать) и мой вариант работает:

Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
Public Type StringToChar
    ByteStr() As Byte
End Type


Function StringToMas(str As String) As StringToChar
    Dim data As StringToChar
    Dim temp As String
    Dim LN As Long
    Dim i As Integer
    Dim ptr As Long
    temp = str
    LN = Len(temp)
    ReDim data.ByteStr(0 To LN)
    If LN > 0 Then
        For i = 0 To LN - 1
            data.ByteStr(i) = Asc(Mid(temp, i + 1, 1))
        Next i
    End If
    data.ByteStr(LN) = 0
    StringToMas = data
End Function

Public Type OpalParamRegistration
  m_protocol As Long 'IntPtr
  m_identifier As Long 'IntPtr
...


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))
    NewMes.m_param.m_identifier = VarPtr(StringToMas("100@192.168.1.3").ByteStr(0))
    NewMes.m_param.m_password = VarPtr(StringToMas("100").ByteStr(0))
    NewMes.m_param.m_timeToLive = 180
    BackMesPtr = OpalSendMessage_Registration(L, NewMes)
    MsgBox BackMesPtr
    If BackMesPtr = 0 Then Exit Sub
    CopyMemory MesType, ByVal BackMesPtr, 4
    If MesType = OpalIndCommandError Then
        Dim p As Long
        CopyMemory p, ByVal BackMesPtr + 4, 4
        MsgBox "Error: " & PtrToString(p)
    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 & _
          "m_hostName: " & PtrToString(s_Registration.m_hostName) & vbCrLf & _
          "m_authUserName: " & PtrToString(s_Registration.m_authUserName) & vbCrLf & _
          "m_password: " & PtrToString(s_Registration.m_password) & vbCrLf & _
          "m_adminEntity: " & PtrToString(s_Registration.m_adminEntity) & vbCrLf & _
          "m_timeToLive: " & s_Registration.m_timeToLive & vbCrLf & _
          "m_restoreTime: " & s_Registration.m_restoreTime & vbCrLf & _
          "m_eventPackage: " & PtrToString(s_Registration.m_eventPackage)
    End If
End Sub


Не растранжирить бы память всеми этими махинациями. Переживаю слегка.

VB.NET (то же самое)
Код: 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.
    Private Sub ButtonRegister_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRegister.Click
        Dim NewMes As OpalDotNET.Opal_API.OpalMessage
        Dim ptrMessage As IntPtr
        Dim BackMes As OpalDotNET.Opal_API.OpalMessage
        NewMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalCmdRegistration
        NewMes.m_param.m_registrationInfo.m_protocol = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("sip")
        NewMes.m_param.m_registrationInfo.m_identifier = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("100@192.168.1.3")
        NewMes.m_param.m_registrationInfo.m_password = Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi("100")
        NewMes.m_param.m_registrationInfo.m_timeToLive = 180
        ptrMessage = OpalDotNET.Opal_API.OpalSendMessage(L, NewMes)
        MsgBox(ptrMessage)
        If (ptrMessage = IntPtr.Zero) Then
            MsgBox("Invalid message")
        Else
            BackMes = CType(Runtime.InteropServices.Marshal.PtrToStructure(ptrMessage, GetType(OpalDotNET.Opal_API.OpalMessage)), OpalDotNET.Opal_API.OpalMessage)
            If (BackMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalIndCommandError) Then
                MsgBox("Error: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_commandError))
            ElseIf (BackMes.m_type = OpalDotNET.Opal_API.OpalMessageType.OpalCmdRegistration) Then
                MsgBox("m_protocol: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_protocol) & vbCrLf & _
                  "m_identifier: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_identifier) & vbCrLf & _
                  "m_hostName: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_hostName) & vbCrLf & _
                  "m_authUserName: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_authUserName) & vbCrLf & _
                  "m_password: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_password) & vbCrLf & _
                  "m_adminEntity: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_adminEntity) & vbCrLf & _
                  "m_timeToLive: " & BackMes.m_param.m_registrationInfo.m_timeToLive.ToString & vbCrLf & _
                  "m_restoreTime: " & BackMes.m_param.m_registrationInfo.m_restoreTime.ToString & vbCrLf & _
                  "m_eventPackage: " & Runtime.InteropServices.Marshal.PtrToStringAnsi(BackMes.m_param.m_registrationInfo.m_eventPackage))
            End If
        End If
    End Sub
...
Рейтинг: 0 / 0
Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
    #37916619
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 Но VB6 app после этого вызова вылетает...( если в Public Type OpalParamRegistration сделать более одного As String)
Дмитрий77Короче зря позарился на "новую версию". Сунул тупо более старые версии opal/ptlib (2-х летней давности), даже не убирая "новоявленных" параметров из структур, и с тем же кодом все зарегистрировалось, long вернулся,
Что интересно, с as Long заданными правильно (как Ptr-ы на правильные char * байт строки) "новая версия" тоже не вылетает и делает чего просют.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Не могу на VB6 осилить Type[struct], Long/String [char */ IntPtr + Marshal.StringToCoTask]
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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