Page 1 of 1

Unicode, pseudotypes and PB4

Posted: Sat May 20, 2006 2:58 pm
by Sub-Routine
I hope someone can help me, please.

I have a program that works well in PB 3.94 by calling Uni2Ascii and Ascii2Uni (COMLIB). I am struggling with some of the conversion to PB4.

I used the Interface Generator from aXend to produce this:

Code: Select all

Interface ISDM3 Extends IDispatch
GetModelStringForDevice(a,b)
EndInterface
In PB 3.94 I can call this function like this:

Code: Select all

oSDM3\GetModelStringForDevice(Ansi2Uni(Devices()\Address), @Model)
    Model_String.s = Uni2Ansi(Model)
Now I modified the Interface for PB4:

Code: Select all

GetModelStringForDevice(a.p-BSTR,b.p-ascii)
And I attempt to call the function:

Code: Select all

oSDM3\GetModelStringForDevice(Devices()\Address, Model_String.s)
The string returned always appears to be empty :?

Thank you,
Rand

Posted: Sat May 20, 2006 4:08 pm
by Sub-Routine
Here is the description of the function:

Code: Select all

[VOffset($178)] HRESULT GetModelStringForDevice([in] BSTR deviceID,
     [out, retval] BSTR* Result)
I can call several other functions successfully, but none that return a string.

Rand

Posted: Sat May 20, 2006 4:24 pm
by srod
The way I read this is that the second parameter to

Code: Select all

GetModelStringForDevice()

should be a pointer to a buffer and so the interface declaration should probably read as follows:

Code: Select all

GetModelStringForDevice(a.p-BSTR,b)
Then pass the address of the string buffer as the second parameter when invoking the method etc.

Must admit that this is a bit of a guess as I'm unable to test any of this at the moment! :)

Posted: Sat May 20, 2006 4:38 pm
by netmaestro
oSDM3\GetModelStringForDevice(Devices()\Address, Model_String.s)
Sorry if I'm out to lunch here, is it possible you could try:

Code: Select all

oSDM3\GetModelStringForDevice(Devices()\Address, @Model_String.s)
It won't break anything to try it, anyway. Aren't we telling the function where we'd like the output string put?

[Edit] Just noticed this, sorry srod!
Then pass the address of the string buffer as the second parameter when invoking the method etc.

Posted: Sat May 20, 2006 4:59 pm
by Sub-Routine
srod wrote:The way I read this is that the second parameter to

Code: Select all

GetModelStringForDevice()

should be a pointer to a buffer and so the interface declaration should probably read as follows:

Code: Select all

GetModelStringForDevice(a.p-BSTR,b)
Then pass the address of the string buffer as the second parameter when invoking the method etc.

Must admit that this is a bit of a guess as I'm unable to test any of this at the moment! :)
Thank you fellow coders. I know this is a tough one and impossible for anyone else to test with this particular interface.

I was doing that in 394 and the function returns Unicode, which I then could convert with COMLIB's Uni2Ansi function. So I guess what I am really asking is how, in PB4, do I convert a Uni to Ascii? I thought using a pseudotype in the interface was the correct method. It obviously works when I pass the first parameter, as other functions return correct responses.

Rand

Posted: Sat May 20, 2006 5:08 pm
by srod
I think that for the first parameter, you're doing the right thing; but for the second you're not actually passing a string, but the address of a buffer. I'm not sure pseudotypes will convert return values on the fly as they do with function arguments etc.

Why not simply use the same Uni 2 Ansi conversion function you did with PB 3.94 for the returned string?

Posted: Sat May 20, 2006 5:31 pm
by ts-soft
to convert the result, you can use this:

Code: Select all

Result.s = PeekS(*ResultPointer, #PB_Any, #PB_UTF8)
Result.s = PeekS(*ResultPointer, #PB_Any, #PB_Unicode)

Posted: Sun May 21, 2006 4:04 pm
by Sub-Routine
Why not simply use the same Uni 2 Ansi conversion function you did with PB 3.94 for the returned string?
I didn't think the COMLIB would work with PB4. I'll give it a shot.

Code: Select all

Result.s = PeekS(*ResultPointer, #PB_Any, #PB_Unicode)
Thank you, this works.

I thought setting PB to use Unicode was going to make this unnecessary.

Thanks again everyone!
Rand

Posted: Tue May 23, 2006 4:40 am
by Esteban1
Sub-Routine wrote:I didn't think the COMLIB would work with PB4. I'll give it a shot.
You don't need COMLIB for that.

Code: Select all

Procedure.s Uni2Ansi(unicodestr.l) 
  lenA = WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, 0, 0, 0, 0); 
  ansistr.s = Space(lenA) 
  If (lenA > 0) 
    WideCharToMultiByte_(#CP_ACP, 0, unicodestr, -1, @ansistr, lenA, 0, 0); 
  EndIf 
  ProcedureReturn ansistr 
EndProcedure 
And this works for PB 4.00 and PB 3.94 too!

Posted: Wed May 24, 2006 12:30 am
by Sub-Routine
Thanks Esteban, it looks like it should work. Do I have to deselect Unicode executable? I get a Unicode string returned.

Rand

Posted: Wed May 24, 2006 2:23 am
by Esteban1
Sub-Routine wrote: Do I have to deselect Unicode executable? I get a Unicode string returned.
Every string returned by a PB function will be in Unicode format if you are compiling with "Create Unicode Executable" option enabled!

So deselect it and the Ansi2Uni function will work the same way as it did in PB 3.94

Posted: Thu May 25, 2006 3:00 am
by Sub-Routine
Every string returned by a PB function will be in Unicode format if you are compiling with "Create Unicode Executable" option enabled!

So deselect it and the Ansi2Uni function will work the same way as it did in PB 3.94
And it does.

Then forgive me for the uninformed question. What is wrong with selecting Unicode executable?

Rand