views:

515

answers:

4

I have an third part dll that have a function that returns a string. When I call the function I got for example "123456" back. At least it seams like that, but when i do mystring.length it does not return any length. If I set the text property of a label it shows "123456".

When I have the string I got from the dll I send it to a webservice function:

rem call dll and get string
dim mystring as string=mydll.getstring()

rem Send it to the webservice
webservice.SaveString(mystring)

The webservice crashes with an webexeption ("protocoll error") when I send in the string I got from the dll. If I instead send it like this:

rem call dll and get string
dim mystring as string=mydll.getstring()

rem Send it to the webservice
dim FixedString as string = mid(mystring,1,6)
webservice.SaveString(mystring)

Then it works and everything is fine. That leads me to think that the string I got from the DLL is in someway not terminated correct. And I dont know how to fix it from vb.net (I cant change the DLL) and I dont know in beforehand how long the string will be.

The dll does only work on site when specific hardware is connected so I can't sit at the office trying to fix this in dev-environment. So I would like to have some possibly solutions to this before I go to the customer again.

Edit 1: I tried to just do a loop that looped from 1 to 100 (because I dont know the real length) and tried to copy all characters that <>"" to a new variable but it didnt work. I didnt try other variants because the day was over and I had to leave the customer site.

Edit 2:
The DLL Im talking to is made in VB6. That DLL is talking to other DLLs that is made in C++ (I think).

My program < - > vb6-DLL <-> c++-DLL <-> hardware

A: 

one possibility would be to convert it to an array of bytes and get the size of the array.

MasterMax1313
A: 

Strings are not null-terminated in .NET, BTW.

I agree with the answer above that says also try converting into bytes and look at the bytes.

If the third-party can't return a valid string, then you can't depend on it to not crash your program, either. Is this a managed DLL, or is it unmanaged code? Is your program multi-threaded, and if so, does this third-party unmanaged DLL work in multi-threaded environments? It's possible that it does not, in which case, you'll have to serialize all access to that DLL.

John Saunders
Im allmost sure this DLL is made in VB6 and is a com-dll.
Stefan
My program is not multithreaded. And it could be possible I can get the Author to fix this if its not fixable on my side.
Stefan
+1  A: 

Check out the MSDN documentation about strings, especially the part about:

In the .NET Framework, a String object can include embedded nulls, which count as a part of the string's length. However, in some languages, such as C and C++, a null character indicates the end of a string, is not considered a part of the string, and is not counted as part of the string's length. This means that the following common assumptions that C and C++ programmers or that libraries written in C or C++ might make about strings are not necessarily valid when applied to String objects:

The value returned by the strlen or wcslen functions does not necessarily equal String.Length.

The string created by the strcpy_s or wcscpy_s functions is not necessarily identical to the string created by the String.Copy method.

You should ensure that native C and C++ code that instantiates String objects, and code that is passed String objects through platform invoke, do not assume that an embedded null marks the end of the string.

Instead I'd do something like:

rem call dll and get string
dim mystring as string=string.intern(mydll.getstring())

(Note: I haven't tried this)

overslacked
Thanks, Ill try that tomorrow.
Stefan
A: 

Strings in VB6 are BSTRs (see this or Google for more).

BSTRs may be not null-terminated, but they all are prepended with an integer denoting their length. So you have a pointer to a memory block which contains an integer and an array of Unicode characters and this pointer points to a string, but there is an integer 4 bytes left storing an integer. You shouldn't access length yourself, instead you should call SysStringLen() (Win32 function) to obtain such strings' length.

sharptooth