Get string from structure filled by C++ functioncall

A

Assido

Hello @all

i need help with the following problem:

Im calling an unmanaged C++ DLL (TAPI32.dll) function (lineGetCallInfo) 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 dwCallParamFlags As Integer
Dim dwCallStates As Integer
Dim dwMonitorDigitModes As Integer
Dim dwMonitorMediaModes 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 dwCallerIDOffset As Integer
Dim dwCallerIDNameSize As Integer
Dim dwCallerIDNameOffset As Integer
Dim dwCalledIDFlags As Integer
Dim dwCalledIDSize As Integer
Dim dwCalledIDOffset As Integer
Dim dwCalledIDNameSize As Integer
Dim dwCalledIDNameOffset As Integer
Dim dwConnectedIDFlags As Integer
Dim dwConnectedIDSize As Integer
Dim dwConnectedIDOffset As Integer
Dim dwConnectedIDNameSize As Integer
Dim dwConnectedIDNameOffset As Integer
Dim dwRedirectionIDFlags As Integer
Dim dwRedirectionIDSize As Integer
Dim dwRedirectionIDOffset As Integer
Dim dwRedirectionIDNameSize As Integer
Dim dwRedirectionIDNameOffset As Integer
Dim dwRedirectingIDFlags As Integer
Dim dwRedirectingIDSize As Integer
Dim dwRedirectingIDOffset As Integer
Dim dwRedirectingIDNameSize As Integer
Dim dwRedirectingIDNameOffset As Integer
Dim dwAppNameSize As Integer
Dim dwAppNameOffset As Integer
Dim dwDisplayableAddressSize As Integer
Dim dwDisplayableAddressOffset As Integer
Dim dwCalledPartySize As Integer
Dim dwCalledPartyOffset As Integer
Dim dwCommentSize As Integer
Dim dwCommentOffset As Integer
Dim dwDisplaySize As Integer
Dim dwDisplayOffset As Integer
Dim dwUserUserInfoSize As Integer
Dim dwUserUserInfoOffset As Integer
Dim dwHighLevelCompSize As Integer
Dim dwHighLevelCompOffset As Integer
Dim dwLowLevelCompSize As Integer
Dim dwLowLevelCompOffset As Integer
Dim dwChargingInfoSize As Integer
Dim dwChargingInfoOffset As Integer
Dim dwTerminalModesSize As Integer
Dim dwTerminalModesOffset As Integer
Dim dwDevSpecificSize As Integer
Dim dwDevSpecificOffset As Integer
End Structure

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

Now the relevant fields in the structure are filled:

- dwCallerIDOffset
- dwCallerIDSize

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

Dim CallingID as String

CallingID = GetStringFromStructure(strucCallinfo,
strucCallinfo.dwCallerIDOffset, strucCallinfo.dwCallerIDSize)

Private Function GetStringFromStructure(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.AllocHGlobal(Marshal.SizeOf(InputStructure))

'// Marshal the structure to the pointer
Marshal.StructureToPtr(InputStructure, ptrToStructure, True)

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

'// Read the string from the new pointer with the specified length
RetString = Marshal.PtrToStringAnsi(ptrToString, Length)

'// Free allocated memory
Marshal.FreeHGlobal(ptrToStructure)

'// 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.
 
A

Armin Zingler

Assido said:
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
(lineGetCallInfo) 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 dwDevSpecificOffset)?
You say "strcCallinfo.dwTotalSize = 1024", but the total size is less.
Maybe I'm wrong(?)


Armin
 
A

Assido

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.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=2048)> Dim ByteBuffer() As Byte

and it works!

Thank you so much!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top