Sign in to follow this  
Followers 0
JRowe

Passing a dll struct to COM object

7 posts in this topic

I've got a com object that's expecting a BSTR instead of a string. Can I construct a BSTR struct using dllstructcreate and pass it to the com object? Or is there another method of passing a BSTR to COM?

http://msdn.microsoft.com/en-us/library/ms221069.aspx

#Include <WinAPI.au3>
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

Global $g_eventerror = 0

$Smilex = ObjCreate("SMILEX.SmileXCtrl.1")
if not IsObj($Smilex) then
    Msgbox(0,"Error","$Smilex is not an Object.")
else
    Msgbox(0,"Error","Successfully created Object $Smilex")
endif

$sBSTR_Struct = DllStructCreate("int;wchar[19];char[2]")
DllStructSetData($sBSTR_Struct, 1, 76)
DllStructSetData($sBSTR_Struct, 2, "c:/test/Animals.dsl")
DllStructSetData($sBSTR_Struct, 3, 0, 1)
DllStructSetData($sBSTR_Struct, 3, 0, 2)

;Here's where things suck
$Result = $Smilex.ReadFile(DllStructGetPtr($sBSTR_Struct))


Func MyErrFunc()
 $HexNumber=hex($oMyError.number,8)
 Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"   & @CRLF & @CRLF & _
    "err.description is: "  & @TAB & $oMyError.description  & @CRLF & _
    "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
    "err.number is: "   & @TAB & hex($oMyError.number,8) & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _
    "err.scriptline is: "   & @TAB & $oMyError.scriptline   & @CRLF & _
    )

 $g_eventerror = 1 ; something to check for when this function returns
Endfunc

I tried to create it and then pass the pointer to the struct, as a BSTR is a pointer.

Can something like this work? Or am I off the reservation on this one?

Share this post


Link to post
Share on other sites



I was unaware of that function's existence. So now I'm getting a ptr returned by the SysAllocString and passing that to the com object, still returning a catastrophic failure.

#Include <WinAPI.au3>
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

Global $g_eventerror = 0

$Smilex = ObjCreate("SMILEX.SmileXCtrl.1")

$hBSTR = DllCall("oleaut32.dll", "ptr", "SysAllocString", "wstr", "c:/test/Animals.dsl")
MsgBox(0, "Seems to work", $hBSTR[0] & @CRLF & @error)

;Here's where things seem to be sucking less, now
$Smilex.ReadFile($hBSTR[0])

Func MyErrFunc()
 $HexNumber=hex($oMyError.number,8)
 Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"   & @CRLF & @CRLF & _
    "err.description is: "  & @TAB & $oMyError.description  & @CRLF & _
    "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
    "err.number is: "   & @TAB & hex($oMyError.number,8) & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _
    "err.scriptline is: "   & @TAB & $oMyError.scriptline   & @CRLF)

 $g_eventerror = 1 ; something to check for when this function returns
Endfunc

Information from the developers:

SmileX implements IDispatch and uses BSTRs for strings. Is it possible to use AutoIt with BSTRs?

I'm not sure if that's relevant at all, but if it helps, then here it is.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Strange. You can verify it's a BSTR object:

#Include <WinAPI.au3>

$hBSTR = DllCall("oleaut32.dll", "hwnd", "SysAllocString", "wstr", "c:/test/Animals.dsl")
$tBSTR = DllStructCreate('byte', $hBSTR[0]-4)
ConsoleWrite(DllStructGetData($tBSTR, 1)/2 & @CRLF)

According to BSTR definition. The variable is pointing to the start of the string -always-. The string is fixed and can only be resized by reallocation, and it has a null wchar_t at the end -always-. So I guess that you need to clarify what this COM library is looking for. The way it's right now, it's a pointer to a valid BSTR object according to these 3 rules.

Edit: Try a few variations like, Ptr($hBSTR[0]) or something like:

$tBSTR = DllStructCreate('ptr', $hBSTR[0])
$pBSTR = DllStructGetPtr($tBSTR)

; Or
$tBSTR = DllStructCreate('ptr')
DllStructSetData($tBSTR, 1, $hBSTR[0])
$pBSTR = DllStructGetPtr($tBSTR)
Edited by Authenticity

Share this post


Link to post
Share on other sites

Everything fails. Not only this, but any method I try to call, at all, results in catastrophic failure. I'd like to punt the guy who coined that term, I think I'd be much less disgruntled if the failure was named something like "temporary setback, no worries."

http://genie.sis.pitt.edu/download/smilex1_0.zip is the activex object I'm working with.

I have it registered correctly, OLE Viewer sees it just fine, so I'm beginning to be baffled.

I tried different alignments, creating a pointer to the pointer, reversing the process and getting a pointer from the pointer. I'm not sure whether this is continuable, I guess.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

If I remember right, you had the same issue with a COM library object, 2 or 3 months ago. with the same error. I think it was different library and I've asked you if it's working with another engine, like JScript or WSH and it turned out the library wasn't working with either. So I've tried this object's simple method AboutBox and this one is not working as well. So either, AutoIt can't handle this such library which is possible or the object got a serious problem. Do you have the source of the library to compile it yourself?

Edit: Tried it with these 2 different engines. As long they're correct, something is broken.

Test.vbs

Dim Smilex : Set Smilex = CreateObject("SMILEX.SmileXCtrl.1")

Smilex.AboutBox
Set Smilex = Nothing

Test.js

var Smilex = new ActiveXObject("SMILEX.SmileXCtrl.1")

Smilex.AboutBox()
delete SmileX
Edited by Authenticity

Share this post


Link to post
Share on other sites

Something is wonky. I'm using winXP SP3 on this system, my acer wont run it either, when I had that issue a few months ago, it was on SP2 and I'd recompiled several times. So either I have a COM gremlin, I'm picking objects that are fundamentally incompatible with my systems, or the objects themselves are broken. I'm talking with one of the Smile devs, maybe they'll release the source for the activex object. If not, then I'll have to write a dll that exposes the functions, or wrap it up in some plugin functions.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0