Why do I only get part of the string returned from this function?

I am trying to use a VB.net 2005 windows application to access function in an unmanaged c based dll that I do not have the source code. It is required to use this dll for reliable messaging with legacy systems. This dll contains a function to read a message off a queue and return the message string and status codes used to test for successfull completion. The function has the following prototype:

int32 pams_get_msg (char * MsgArea,char * Priority,q_address * Source,short * msgClass,short * MsgType,short * MsgAreaLen,

short * LenData,int32 * SelFilter,struct PSB * PSB,struct show_buffer * ShowBuff,int32 * ShowBuffLen,

int32 * LargeAreaLen,int32 * LargeSize,char * NullArg1);

Argument Data Type Mechanism Prototype Access

msg_area char reference char * returned

priority char reference char * passed

source q_address reference q_address * returned

class short reference short * returned

type short reference short * returned

msg_area_len short reference short * passed

len_data short reference short* returned

[sel_filter] int32 reference int32 * passed

[psb] struct psb reference struct psb * returned

[show_buffer] struct show_buffer reference struct show_buffer * returned

[show_buffer_len] int32 reference int32 * passed

[large_area_len] int32 reference int32 * passed/returned

[large_size] int32 reference int32 * returned

[nullarg_3] char reference char* passed

I have the function declare in VB as:

DeclareFunction pams_get_msgLib"dmq.dll" (ByVal MsgAreaAs StringBuilder,ByRef PriorityAsByte,ByRef SourceAs QAddress,ByRef msgClassAsShort,ByRef MsgTypeAsShort,ByRef MsgAreaLenAsShort,ByRef LenDataAsShort,ByRef SelFilterAsInteger,ByRef PSBAs PSB,ByRef ShowBuffAs ShowBuffer,ByRef ShowBuffLenAsInteger,ByRef LargeAreaLenAsInteger,ByRef LargeSizeAsInteger,ByVal NullArg1AsInteger)AsInteger

Calling code:

Dim msgAsNew StringBuilder(31500)

Dim statusAsInteger

Static show_bufferAs ShowBuffer

Dim show_bufflenAsInteger

Dim large_area_lenAsInteger

Dim large_sizeAsInteger

Dim nullrefAsInteger

show_bufflen = SHOW_BUFFER_LEN

large_area_len = 0

nullref =Nothing

status = pams_get_msg(msg, msg.Priority, msg.SrcTarget, msg.dmqClass, msg.dmqType, 31500, msg.MsgLen, msg.SelFilter, msg.PSB, show_buffer, show_bufflen, large_area_len, large_size, nullref)

Result:

I get a good status and good return parameter values except for the message itself. I can only see the message number which is the first few characters in the string--NOT the entire message. Where is the rest of the string and how can I access it? If I make the msg size in VB (say msg(1024) )smaller than the actual message it knows it and fails, but as soon I make it big enough it succeeds but I can't see the whole message. Am I missing something in the unmanaged to managed transistion?

Thanks for any help!

[7808 byte] By [jmass17] at [2007-12-28]
# 1
Try declaring your function Declare Ansi Function.
AlexMoura at 2007-9-4 > top of Msdn Tech,Visual Basic,Visual Basic Interop and Upgrade...
# 2

I tried that and it made no difference, I still get only part of the message, but successfull return status.

I have it declared like this :

Declare Ansi Function pams_get_msg Lib "dmq.dll" (ByVal MsgArea As StringBuilder, ByRef Priority As Byte, ByRef Source As QAddress, ByRef msgClass As Short, ByRef MsgType As Short, ByRef MsgAreaLen As Short, ByRef LenData As Short, ByRef SelFilter As Integer, ByRef PSB As PSB, ByRef ShowBuff As ShowBuffer, ByRef ShowBuffLen As Integer, ByRef LargeAreaLen As Integer, ByRef LargeSize As Integer, ByVal NullArg1 As Integer) As Integer

Then from windows app:

Dim I_msg As New StringBuilder(31500)

status = pams_get_msg(I_msg, msg.Priority, msg.SrcTarget, msg.dmqClass, msg.dmqType, 31500, msg.MsgLen, msg.SelFilter, msg.PSB, show_buffer, show_bufflen, large_area_len, large_size, nullref)

MsgBox(I_msg.Length) 'came back as 5, the length of the msg number 25102

MsgBox((I_msg).ToString) 'came back with only the message number 25102 or first 5 characters of message that is 4133 characters long.

The full message is 4133 characters long and starts like this:

25102--4:Insert into .......

Any other ideas on how to get the rest of the message?

Thanks in advance

jmass17 at 2007-9-4 > top of Msdn Tech,Visual Basic,Visual Basic Interop and Upgrade...
# 3
Hmm.. your definition looks good. Perhaps it's just something unusual with the StringBuilder object itself. being uninitialized.

Try your usage as such:
Dim l_msg As New StringBuilder("")
...
...
...
l_msg.Capacity = 31500
status = pams_get_msg( l_msg, ........ etc.etc.)

Last but not least, you may wish to make a C/C++ project that uses your unmanaged DLL directly to inspect the contents of the returning string. It's possible there are imbedded binary bytes in the string that is confusing VB's wrappers on return. When the memory pointer is sent off to a DLL, it has to figure out on return how long the string is on the way back. If your message has any non-text bytes within, this could be throwing the wrapper. A native C/C++ interface to test this might yield insight by walking through the char buffer byte by byte to see if your DLL is doing something naughty with the string.

StevePO at 2007-9-4 > top of Msdn Tech,Visual Basic,Visual Basic Interop and Upgrade...