Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

String pointer problems 1

Status
Not open for further replies.

LuckyStarr

Programmer
Sep 12, 2002
22
BR
Hi Folks,

I have a problem, and I hope you can help me. Let me explain: I have some functions in a C DLL. And I call this functions from the VB code.

The problem is occuring with a function that has a string being passed from VB to the DLL(the string will be filled by the DLL function), using ByVal in the VB.

When I debug the C code, I can see that the pointer received by the DLL function is NULL. But If I use ByRef in VB, my program doesn't work.

The point is: Should I pass Strings using ByRef or ByVal to the DLL?

I would be glad if someone could explain me the difference between Strings in C and in VB.

Thanks!
 
You should pass them ByVal, since VB automatically sends in a pointer when sending strings into the dll.

However, you need to initialize it first:

Dim strParm as String
strParm = String(255,0)


since the dll is probably expecting a pointer to an already existing block of memory.

Greetings,
Rick
 
The difference is that in C, strings are handled as an LPSTR type, that being that the address of a string points to the value of the string. However is VB, strings are of type BSTR which means that the address of the string is a pointer to an LPSTR type (which in turn points to the value of the string), in addition to some other information about the string, because in VB strings are Unicode.

Therefore, since the Value of a string address in VB is a pointer to a LPSTR type, and C is expected an LPSTR type for its string, you pass the VB String pointer by value, which means that C gets the LPSTR type.

Good Luck
--------------
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
>>However is VB, strings are of type BSTR which means that the address of the string is a pointer to an LPSTR type (which in turn points to the value of the string), in addition to some other information about the string, because in VB strings are Unicode.

This is not entirely true;
This pointer points directly to the first character of the string, not to another pointer that points to the string.

Furthermore, the four bytes before the start of the string contain the length of the string.


So actually the VB string (BSTR) looks like this:
DDDDPPCCCCCCCC, where

DDDD = length of string (DWORD).
PP = first character of the string and the address that the BSTR points to.
CC = second, third etc. characters of the string.


Greetings,
Rick
 
>This pointer points directly to the first character of the string

No, no, CajunCenturion is correct (and McKinney is wrong, as is the VB documentation on this). A VB string variable is a pointer to a BSTR, which is itself a pointer to a wide character (or Unicode) string. Here's the C type definition of a BSTR:

typedef OLECHAR FAR* BSTR

And the undocumented VarPtr and StrPtr functions, when applied to string variables, reflect this:

VarPtr returns the pointer to the (BSTR) pointer
StrPointer returns the BSTR pointer that VarPtr points to.


Now most of the time, even when making API calls, you don't have to worry about this. Behind the scenes VB does all the hard work for you (including converting between Unicode and ANSI). Essentially, when you make an API call with a 'ByRef As String' parameter, VB actually makes a new, temporary BSTR containing a null-terminated ANSI string, and then passes the BSTR pointer. Since this pointer actually points (as LazyMe says) to the first character of the ANSI string it can be, in most cases, treated exactly as if it is an LPSTR. On returning from the call, the temporary BSTR is converted back into Unicode and copied back into the original BSTR.

 
So, discarding any API call conversion etc., just in "plain VB", we're actually working with pointers to BSTR's? This, to me, seems like a major flaw in any VB string documentation read so far...
It would mean that VB strings are BSTR*, not BSTR.


And now for the COM calls which, until so far, I suspected didn't need any conversion when working with strings:

VB converts our string, below the surface, to an actual BSTR when expected by the server? Or rather; sends in the pointer that the string variable points to, instead of the variable we're working with in VB?

Greetings,
Rick
 
COM calls don't need any conversion. COM strings are BSTRs. And VB strings are natively BSTRs (which are pointers to OLECHAR)
 
Yes I know they're BSTRs. That's why I was wondering, since the VB string vars we're working with turn out to be BSTR pointers instead of plain BSTRs, (which I always thought they were) if I'm sending in a VB string var (which is a BSTR* and not a BSTR) in a COM server expecting a BSTR, VB can't send in the string var we're working with, it needs to send in the BSTR it's pointing to, am I right?


Or am I undertanding your point entirely wrong?

I mean; I know that the BSTR itself is actually a pointer (this is the one that points to the first character bla bla bla...). But, until so far, I've always thought that a VB string var holds that pointer; just like when in C working with the BSTR. However, from your first post here I have understood that the VB string var holds a pointer to a BSTR so if translated in typedefs etc:

typedef WCHAR OLECHAR (on win 32 platforms)
typedef OLECHAR FAR* BSTR

So a BSTR actually is a pointer to a WCHAR. No matter the possiblitly of embedded NULLs or the fact that the array of characters is preceeded by a length indicator, because this is only important and recognized by the BSTR manipulation APIs. So conversion is possible quite simple; (WCHAR*)BSTR and there's the string.

Now if the VB string is actually a pointer to the BSTR, like you said in your post, this would mean that the "definition" of the VB string variable would have to be like WCHAR**, a pointer to a wide character pointer, correct?


So, here's the big question (finally):
Is the VB string var a BSTR (WCHAR*) or a BSTR* (WCHAR**).

Greetings,
Rick
 
a string in vb is a pointer

to quote MS "The BSTR is the actual pointer variable. It has size 32 bits, like all pointers, and points to a Unicode character array. Thus, a Unicode character array and a BSTR are not the same thing. It is correct to refer to a BSTR as a string (or VB string) but, unfortunately, the Unicode character array is also often called a string! Hence, we will not refer to a BSTR simply as a string--we will refer to it by its unequivocal name--BSTR."

typedef wchar_t * BSTR;

WCHAR = wchar_t = OLECHAR

which is much like

typedef wchar_t * LPWSTR;
typedef char * LPSTR;
 
That's exactly what I thought too. But according to strongm the documentation (which more or less states what you said), that documentation is incorrect.

strongm states:
A VB string variable is a pointer to a BSTR, which is itself a pointer to a wide character (or Unicode) string.

It's not the last part that's confusing me, this is what you state and what I already knew. The part that's confusing me is the first part (A VB string variable is a pointer to a BSTR). That's something I did not know and I HATE to be confused.....

Greetings,
Rick
 
>A VB string variable is a pointer to a BSTR, which is itself a pointer to a wide character (or Unicode) string

Let me try and rephrase the above in the hopes of being clearer:

A variable that represents a string for a programmer in a VB program is a pointer to the underlying BSTR.

In other words, the 'string variable' that we get direct access to in VB as programmers are not the native VB string type (which is indeed a BSTR), merely pointers to them. VB provides a kind of 'string presentation layer' to the programmer, so they don't have to (normally) worry about how BSTRs work.
 
Ah, ok. So internally it's all regular BSTR, only the variables we use as string vars point to the BSTR, they are not actual BSTR's.

Well, you can't stop learning I guess...


Thanks for the explanation.

Greetings,
Rick
 
nature of learning. You can hear 10 different people describe the same thing but it doesn't always sink in the first 9 times. The 10th time might just change the way they describe one little thing and BAM evrything falls into place. I don't think this is negative on the person being told. This is were smart people shine in the ability to listen to other people and not just blindly believe the way things where. Just like I learn that Jet has transaction 8)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top