From: ralph on
On Sun, 18 Jul 2010 12:13:39 +1000, Leo <ttdhead(a)gmail.com> wrote:

>Jim Mack wrote :
>> Leo wrote:
>>> I have some code I am thinking of sticking in a standard dll which
>>> needs to have strings passed to it. What is the best way to do this
>>> with me seeing the chance that non VB code could be calling this
>>> code. Should I use pointers and convert to a VB string?
>>
>> What language would you use to write this DLL?
>
>VB

It is possible to create a "standard DLL" with VB, but it is not
common as you have to jump through some additional hoops, (as Mayayana
pointed out), so I have to ask - are you sure you meant to say that?

In case you are creating a standard DLL the problem will be that the
VB Runtime always converts a VB BSTR (Unicode internally) to an ANSI
BSTR *before* it passes a string to a standard DLL. This happens
whether you are specifically Declaring to pass a BSTR or if a LPSTR
(or any LP??STR) to a character array. So you may find you need to do
the conversions as suggested by Mayayana.

However, it you use an ActiveX DLL instead, the VB BSTR is identical
to a OLE BSTR as defined in OLE2, thus Unicode, thus no conversions.

Other languages can work with the strings as either a BSTR or as a
LP??STR.

hth
-ralph
From: Leo on
ralph pretended :
> On Sun, 18 Jul 2010 12:13:39 +1000, Leo <ttdhead(a)gmail.com> wrote:
>
>> Jim Mack wrote :
>>> Leo wrote:
>>>> I have some code I am thinking of sticking in a standard dll which
>>>> needs to have strings passed to it. What is the best way to do this
>>>> with me seeing the chance that non VB code could be calling this
>>>> code. Should I use pointers and convert to a VB string?
>>>
>>> What language would you use to write this DLL?
>>
>> VB
>
> It is possible to create a "standard DLL" with VB, but it is not
> common as you have to jump through some additional hoops, (as Mayayana
> pointed out), so I have to ask - are you sure you meant to say that?
>
> In case you are creating a standard DLL the problem will be that the
> VB Runtime always converts a VB BSTR (Unicode internally) to an ANSI
> BSTR *before* it passes a string to a standard DLL. This happens
> whether you are specifically Declaring to pass a BSTR or if a LPSTR
> (or any LP??STR) to a character array. So you may find you need to do
> the conversions as suggested by Mayayana.
>
> However, it you use an ActiveX DLL instead, the VB BSTR is identical
> to a OLE BSTR as defined in OLE2, thus Unicode, thus no conversions.
>
> Other languages can work with the strings as either a BSTR or as a
> LP??STR.
>
> hth
> -ralph

I did mean to say a Standard DLL built using VB. I have vbAdvance
installed which will do the extra stuff for me.

--
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Free usenet access at http://www.eternal-september.org


From: Kevin Provance on

"Leo" <ttdhead(a)gmail.com> wrote in message
news:i1u7jr$rj9$1(a)news.eternal-september.org...
: ralph pretended :
: I did mean to say a Standard DLL built using VB. I have vbAdvance
: installed which will do the extra stuff for me.

When you are working on your VB code for the DLL, any function or sub that
passes a string or returns one will requires the following. It just so
happens I was working on this last night. Here is a function that does
both.

'Air code
Function TestStrings (ByVal sInput As String) As String
Dim sInternalStr As String
Dim sRetStr As String

sInternalStr = StrConv(sInput, vbUnicode)
'you can now do whatever you want with the passed string

MsgBox sInternalStr, ,"My DLL Test"

'retuurning a sttring value requires the following
sRetStr = "Passed back to the app"
TestStrings = StrConv(sRetStr, vbFromUnicode)
End Function

Whenever you pass or return strings in your VB DLL, you have to do that
conversion, since VB is not automatically doing it for you anymore.

Okay, now you do the compile thing and make your DLL. You would declare it
in your project as follows:

Private Decalre Function TestStrings Lib "MyDll.dll" (ByVal sInput As
String) As String

When writing your DLL code, any parameters you pass as ByVal, you must
declare as ByVal in your project. Anything ByRef, declare as such, or leave
blank. As far as I know, when authoring a DLL in VB, there is no option to
declare As Any. If that is untrue, and anyone else knows a way, please feel
free to correct me. :-)

- Kev

From: ralph on
On Sun, 18 Jul 2010 16:40:31 +1000, Leo <ttdhead(a)gmail.com> wrote:


>
>I did mean to say a Standard DLL built using VB. I have vbAdvance
>installed which will do the extra stuff for me.

Ok. Always good to make sure. <g>

What you do is compensate for the hidden conversion by converting it
first. So your calls will look like this ...

' client
' A call that takes a string and changes it
Declare Sub MangleAString Lib "MyStandard.dll"
(ByRef vbBSTR As String)
....
Dim sSomeString As String
' Convert to a unicode character array
' It doesn't matter that is already Unicode
' StrConv will blindly convert every "byte" of the existing BSTR
' and expand it to Unicode (* Note below)
sSomeString = StrConv(sSomeString, vbUnicode)
MangleAString sSomeString
sSomeString = StrConv(s, vbFromUnicode)
....

* This seldom makes a lot of sense at first sight. <g>
But here is what happens ...

Say the first character is an 'a', in Unicode it is 0061 hex.
In memory this is 61 00
Each byte is converted to Unicode which results in ...
61 00 00 00
(We have inserted a Unicode null character between each Unicode
character in the original string.)
When VB goes to pass the string it will convert the "Unicode" to
"ANSI" which is to strip out the null unicode characters ... which
returns the string to it original state.
61 00
Thus we have faked-out the VB *feature*. VB thinks he is passing ANSI.

Now, when the mangled string returns from the call VB politely expands
the string to Unicode, ie, the above in reverse. Again it doesn't
matter it is actually Unicode - VB *assumes* it is ANSI since it came
from a Standard DLL thus blindly expands it by inserting null
characters. So we convert to 'ANSI' by removing the padding - which
again the result is actually Unicode.

This should help with any variations you might run into.

(Just noticed Kevin already answered while I was writing, but I'll
send along anyway as an amplification.)

-ralph
From: ralph on
On Sun, 18 Jul 2010 10:41:23 -0400, "Kevin Provance" <k(a)p.c> wrote:


>... As far as I know, when authoring a DLL in VB, there is no option to
>declare As Any. If that is untrue, and anyone else knows a way, please feel
>free to correct me. :-)
>

There isn't.

The "As Any" is only meaningful to the 'client' that is using a
Declare directive that defines it.

VB always does a bit of processing behind the scenes when passing
calls to a standard DLL. For example, as already noted it converts VB
BSTRs to ANSI BSTRs. It also does a bit of parameter validation and
coercion if needed. So it depends on the specific datatype passed or
returned in the Call that determines what VB will do with an "Any".

In general the "As Any" can be consider a 32-bit pointer, so depending
on what it is you are trying to do you may get away with a 'pointer'
or VB Long. (But in my experience it often fails. <g>)

ie, "As Any" is a hack, not a datatype.

IMHO, if you are exporting a routine that can take multiple
expressions you are better off providing separate routines each with a
specific defined type.
eg.
GetWindowHandle () As Long
GetWindowName () As String

Or perhaps a Type with elements filled with each of the possibilities.

But you need to explain a bit more why you need the "As Any".

-ralph
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: New form on Main thread.
Next: Pasting text to browser