Get string from structure filled by C++ functioncall

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?QXNzaWRv?=

    #1

    Get string from structure filled by C++ functioncall

    Hello @all

    i need help with the following problem:

    Im calling an unmanaged C++ DLL (TAPI32.dll) function (lineGetCallInf o) like
    this:

    Declare Function lineGetCallInfo Lib "tapi32.dll " (ByVal hCall As Integer,
    ByRef lpCallInfo As LINECALLINFO) As Integer

    Public Structure LINECALLINFO
    Dim dwTotalSize As Integer
    Dim dwNeededSize As Integer
    Dim dwUsedSize As Integer
    Dim hLine As Integer
    Dim dwLineDeviceID As Integer
    Dim dwAddressID As Integer
    Dim dwBearerMode As Integer
    Dim dwRate As Integer
    Dim dwMediaMode As Integer
    Dim dwAppSpecific As Integer
    Dim dwCallID As Integer
    Dim dwRelatedCallID As Integer
    Dim dwCallParamFlag s As Integer
    Dim dwCallStates As Integer
    Dim dwMonitorDigitM odes As Integer
    Dim dwMonitorMediaM odes As Integer
    Dim DialParams As LINEDIALPARAMS
    Dim dwOrigin As Integer
    Dim dwReason As Integer
    Dim dwCompletionID As Integer
    Dim dwNumOwners As Integer
    Dim dwNumMonitors As Integer
    Dim dwCountryCode As Integer
    Dim dwTrunk As Integer
    Dim dwCallerIDFlags As Integer
    Dim dwCallerIDSize As Integer
    Dim dwCallerIDOffse t As Integer
    Dim dwCallerIDNameS ize As Integer
    Dim dwCallerIDNameO ffset As Integer
    Dim dwCalledIDFlags As Integer
    Dim dwCalledIDSize As Integer
    Dim dwCalledIDOffse t As Integer
    Dim dwCalledIDNameS ize As Integer
    Dim dwCalledIDNameO ffset As Integer
    Dim dwConnectedIDFl ags As Integer
    Dim dwConnectedIDSi ze As Integer
    Dim dwConnectedIDOf fset As Integer
    Dim dwConnectedIDNa meSize As Integer
    Dim dwConnectedIDNa meOffset As Integer
    Dim dwRedirectionID Flags As Integer
    Dim dwRedirectionID Size As Integer
    Dim dwRedirectionID Offset As Integer
    Dim dwRedirectionID NameSize As Integer
    Dim dwRedirectionID NameOffset As Integer
    Dim dwRedirectingID Flags As Integer
    Dim dwRedirectingID Size As Integer
    Dim dwRedirectingID Offset As Integer
    Dim dwRedirectingID NameSize As Integer
    Dim dwRedirectingID NameOffset As Integer
    Dim dwAppNameSize As Integer
    Dim dwAppNameOffset As Integer
    Dim dwDisplayableAd dressSize As Integer
    Dim dwDisplayableAd dressOffset As Integer
    Dim dwCalledPartySi ze As Integer
    Dim dwCalledPartyOf fset As Integer
    Dim dwCommentSize As Integer
    Dim dwCommentOffset As Integer
    Dim dwDisplaySize As Integer
    Dim dwDisplayOffset As Integer
    Dim dwUserUserInfoS ize As Integer
    Dim dwUserUserInfoO ffset As Integer
    Dim dwHighLevelComp Size As Integer
    Dim dwHighLevelComp Offset As Integer
    Dim dwLowLevelCompS ize As Integer
    Dim dwLowLevelCompO ffset As Integer
    Dim dwChargingInfoS ize As Integer
    Dim dwChargingInfoO ffset As Integer
    Dim dwTerminalModes Size As Integer
    Dim dwTerminalModes Offset As Integer
    Dim dwDevSpecificSi ze As Integer
    Dim dwDevSpecificOf fset As Integer
    End Structure

    Dim strucCallinfo As LINECALLINFO
    strcCallinfo.dw TotalSize = 1024
    Dim ret As Integer = lineGetCallInfo (dwDevice, strucCallinfo)
    '..... more code

    Now the relevant fields in the structure are filled:

    - dwCallerIDOffse t
    - dwCallerIDSize

    Like I understand it, the structure has an address in memory (pointer). Now
    I have to add the dwCallerIDOffse t to the address.
    I've done that in this way:

    Dim CallingID as String

    CallingID = GetStringFromSt ructure(strucCa llinfo,
    strucCallinfo.d wCallerIDOffset , strucCallinfo.d wCallerIDSize)

    Private Function GetStringFromSt ructure(ByVal InputStructure As Object,
    ByVal Offset As Integer, ByVal Length As Integer) As String
    Dim RetString As String = ""
    Dim ptrToStructure As IntPtr
    Dim ptrToString As IntPtr

    '// Allocate memory for a new pointer
    ptrToStructure = Marshal.AllocHG lobal(Marshal.S izeOf(InputStru cture))

    '// Marshal the structure to the pointer
    Marshal.Structu reToPtr(InputSt ructure, ptrToStructure, True)

    '// Create a new pointer with the offset to the string
    ptrToString = New IntPtr(ptrToStr ucture.ToInt32 + Offset)

    '// Read the string from the new pointer with the specified length
    RetString = Marshal.PtrToSt ringAnsi(ptrToS tring, Length)

    '// Free allocated memory
    Marshal.FreeHGl obal(ptrToStruc ture)

    '// Return the extracted string
    Return RetString

    End Function


    But everything i get is some ASCII-Salad like "°oæàoæpæ"

    What's wrong here? When i use the same function with an other structure
    filled by a functioncall everything works fine :-(

    So please help me, before it drives me crazy.

  • Armin Zingler

    #2
    Re: Get string from structure filled by C++ functioncall

    "Assido" <Assido@discuss ions.microsoft. comschrieb
    Hello @all
    >
    i need help with the following problem:

    Which OS do you use? It fails on a 64 bit OS. See changes below.
    Im calling an unmanaged C++ DLL (TAPI32.dll) function
    (lineGetCallInf o) like this:
    >
    Declare Function lineGetCallInfo Lib "tapi32.dll " (ByVal hCall As
    Integer,
    ByRef lpCallInfo As LINECALLINFO) As Integer
    Declare Function lineGetCallInfo Lib "tapi32.dll " (ByVal hCall As
    IntPtr, ByRef lpCallInfo As LINECALLINFO) As Integer
    Dim hLine As Integer
    Dim hLine As Intptr


    At first glance I don't see an error in the code (only replace ToInt32
    by ToInt64 on 64 bit OS (see IntPtr.Size)).

    ...Just one thing: Don't you have to reserve additional memory inside the
    structure for the Strings to be returned (after dwDevSpecificOf fset)?
    You say "strcCallinfo.d wTotalSize = 1024", but the total size is less.
    Maybe I'm wrong(?)


    Armin

    Comment

    • =?Utf-8?B?QXNzaWRv?=

      #3
      Re: Get string from structure filled by C++ functioncall

      Hi Achim,

      you are my hero! This is the result of crawling the sourcecode for mistakes
      for days without taking a little break!

      You are absoutly right! The CALLINFO-Structure has to contain a Bytearray to
      reserve enough memory for the strings returned by the functioncall. I just
      added
      <System.Runtime .InteropService s.MarshalAs(Run time.InteropSer vices.Unmanaged Type.ByValArray , SizeConst:=2048 )Dim ByteBuffer() As Byte

      and it works!

      Thank you so much!


      "Armin Zingler" wrote:
      "Assido" <Assido@discuss ions.microsoft. comschrieb
      Hello @all

      i need help with the following problem:
      >
      >
      Which OS do you use? It fails on a 64 bit OS. See changes below.
      >
      Im calling an unmanaged C++ DLL (TAPI32.dll) function
      (lineGetCallInf o) like this:

      Declare Function lineGetCallInfo Lib "tapi32.dll " (ByVal hCall As
      Integer,
      ByRef lpCallInfo As LINECALLINFO) As Integer
      >
      Declare Function lineGetCallInfo Lib "tapi32.dll " (ByVal hCall As
      IntPtr, ByRef lpCallInfo As LINECALLINFO) As Integer
      >
      Dim hLine As Integer
      >
      Dim hLine As Intptr
      >
      >
      At first glance I don't see an error in the code (only replace ToInt32
      by ToInt64 on 64 bit OS (see IntPtr.Size)).
      >
      ...Just one thing: Don't you have to reserve additional memory inside the
      structure for the Strings to be returned (after dwDevSpecificOf fset)?
      You say "strcCallinfo.d wTotalSize = 1024", but the total size is less.
      Maybe I'm wrong(?)
      >
      >
      Armin
      >
      >

      Comment

      Working...