Prev: New form on Main thread.
Next: Pasting text to browser
From: ralph on 18 Jul 2010 02:35 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 18 Jul 2010 02:40 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 18 Jul 2010 10:41 "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 18 Jul 2010 11:44 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 18 Jul 2010 12:25 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 |