Schmidt
7/10/2012 4:12:00 PM
Am 10.07.2012 13:25, schrieb Andrej Viktorovich:
> What's a problem with ByRef?
With ByRef As String, VB is passing the VarPtr(strVariable)
(the descriptor, as ObiWan already said) ...
Whereas with ByVal As String in the Declare, VB is passing
the StrPtr(strVariable) ...the current "Pointer-to-strContent"
which the Descriptor holds.
So at the C-side of things, you will have to dereference
the incoming "Pointer-to-a-Pointer" first (in case of ByRef).
There's an additional thing which takes place under the hood:
VB-Strings are of type BSTR, which hold 16Bit-WChars...
so these strings pointers are not passed directly to the
C-Side of things - instead an implicite ANSI-conversion
takes place - and VB is then passing the appropriate
*temporary* Pointer to the ANSI-Content, or the Tmp-Variables
Pointer which holds the Pointer to the ANSI-Content directly
(depending on ByVal or ByRef) to the Dll-Function.
But that 8BitChar-conversion-mechanism works transparently,
so what's statet on top (with regards to either VarPtr
or StrPtr-passing in case of ByRef or ByVal) remains true
nonetheless.
So the mentioning of this ANSI-stuff was just for completeness...
In case you do declare ByVal - and then compare for example
the value of the incoming Char-Pointer at the C-Side, with
the Value VB spits out when you do:
Debug.Print StrPtr(strVariable).
Then the Value of the CharPtr on the C-side of things will
always differ from what Debug.Print StrPtr(strVariable)
will report at the VB-End... as said, this is due to the
"ANSI-automatics" VB performs under the hood, in case
you define a Param within a VB-DllFunc-Declare "As String"
(no matter, if ByRef or ByVal).
If you want to avoid this VB-ANSI-automatic (e.g. when
your C-Dlls understands "Unicode on Windows" and was set up,
to work with WChars), then just define the String-Params in
your VB-Declare "ByVal As Long" - and pass StrPtr(strVariable)
instead of just strVariable from the VB-end.
Olaf