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).