Page 1 of 1

How do I convert to BSTR?

Posted: Wed Feb 22, 2006 8:10 am
by kyleh
I just purchased PureBasic this past weekend so I’m still new to the language. I’m trying to use PureBasic to interface with other programs. I was using the very cool Interface Generator tool, but I’m having some problems.

Here’s an example of the C++ function I’m trying to access:

[VOffset($24)] HRESULT LogMessage([in] BSTR in_Message,
[in, optional, defaultvalue=8] siSeverity in_Severity)

The interface generator creates code that looks like this:

Interface Application Extends IDispatch
LogMessage(a,b)
EndInterface


I did some searches on the forums and I found some info about converting strings to BSTR, but nothing that works so far. If I try and pass it a string I get an error: “Bad parameter type, number expected instead of string” so I think I need to pass it a pointer, but I’m not sure.

Does anyone know how I can convert a string into a BSTR (a Unicode string?) and get the pointer?

Posted: Wed Feb 22, 2006 8:24 am
by Flype
did you try the prototype with 'p-bstr' type of purebasic 4 ?
something like that:

Code: Select all

Prototype.l LogMessage(InMessage.p-bstr,DefaultValue=8)

Posted: Wed Feb 22, 2006 8:55 am
by Bonne_den_kule
p-bstr is a pointer to a bstr.
Correct if I am not wrong.

Posted: Wed Feb 22, 2006 11:38 am
by Fred
Flype is right, using this pseudo-type will automatically convert PB string in a BSTR one, so it should work.

Posted: Thu Feb 23, 2006 5:05 am
by kyleh
Thank you! Prototypes look like the way to go :)

I was reading about prototypes in the readme file and it's still not clear to me how to use it with a DLL. Could I do something like this? not that this works, I really don't understand how this should come together just yet.

Code: Select all

OpenLibrary(0, "core.dll")
Prototype.l LogMessage(InMessage.p-bstr,DefaultValue=8)
LogMessage ( "test...",8 )

also, can I use 'Interface' like I was before to access COM objects? If so how do I prototype the COM object? I guess I would still need to lookup the required types for the parameters.
sample interface:

Code: Select all

Interface OGLTexture Extends IDispatch
  get_Width(a)
  get_Height(a)
  get_FullName(a)
EndInterface 

Posted: Thu Feb 23, 2006 12:07 pm
by Fred
kyleh wrote:

Code: Select all

OpenLibrary(0, "core.dll")
Prototype.l LogMessage(InMessage.p-bstr,DefaultValue=8)
LogMessage ( "test...",8 )
About the prototype, it just define a new type (like a structure, interface etc.). So you have to affect this type to a variable, and use GetFunction() to get the address of the real function:

Code: Select all

Prototype.l LogMessagePrototype(InMessage.p-bstr,DefaultValue=8)

OpenLibrary(0, "core.dll")

LogMessage.LogMessagePrototype = GetFunction(0, "LogMessage")
if LogMessage ; is the function really found ?
  LogMessage ( "test...")
endif

Posted: Thu Feb 23, 2006 5:01 pm
by kyleh
When I use this I'm getting an Assembler Error.
PureBasic.asm [68]:
CALL _SYS_ToUnicode@4
error: undefined symbol

I'm sure I'm still missing something, but I can't find any information on this error.

Code: Select all

Prototype.l LogMessagePrototype(InMessage.p-bstr,DefaultValue=8)

OpenLibrary(0, "core.dll")

LogMessage.LogMessagePrototype = GetFunction(0, "LogMessage")
if LogMessage ; is the function really found ?
  LogMessage ( "test...")
endif 
[/code]

Posted: Thu Feb 23, 2006 7:01 pm
by Fred
You found a bug, it will be fixed for the next beta, thanks !

Posted: Thu Feb 23, 2006 8:36 pm
by kyleh
Thanks for all your help! I'm looking forward to the next update :)

Posted: Fri Feb 24, 2006 4:54 am
by kyleh
So, it turns out I really need to get a program done for work soon and I would like to use Purebasic. Since I don't know when the next beta is going to be released is there an easy way to do the same thing without Prototype?

Posted: Fri Feb 24, 2006 1:02 pm
by Fred
Sure, you just have to use 'MultiByteToWideChar' to convert your string in unicode (not needed if you compile with 'unicode' mode) and then call SysAllocString() to create a BSTR string. (and then SysFreeString() to free it).