Using Non-Rev DLLs With Revolution |
|
Let me step in here - there's actually two things to talk about: the first is what it means to be 'compiled specifically for RunRev', and the other is how to work with "normal" Windows DLLs from Rev.
Here's the basic situation: When you build a DLL under Windows, you need to provide information in the DLL that provides other applications the ability to call on the function(s) in the DLL (its API). DLLs that are used by most third party Windows apps have a common (standard) API.
Revolution, on the other hand, requires a specific API be used that is not the same one used by other third-party DLLs, and is designed so that RunRev can "attach" the DLL to a stack and you can just naturally call the functions inside it (like the revXML DLL). You can download the Externals toolkit from RunRev and I believe there's information in there about what is required.
As to third-party DLLs that use the common API (which I'll call "Non-Rev DLLs"), you can use them with Revolution, it's just that it takes an intermediary 'agent' to take the request from Rev, pass it off to the DLL, and return a result. I have done this with DLLs that I've created in Visual Basic - the intermediary 'agent' in this case was the execution of a VBS script from Rev (more on this in a minute).
To register a Non-Rev DLL, you use the 'regsvr32' command line. The DLL doesn't have to be in the Windows directory; it can be anywhere - you just will be passing in the path to the DLL when you register it (and DON'T MOVE IT after it's been registered! :-)
Here's the handlers I use for registering and unregistering these DLLs (watch line wraps):
on stsRegisterDLL pDLLPath,pClass
if pClass ="" then put "Main" into pClass
set the itemDel to "/"
put last item of pDLLPath into tDLLName
put char 1 to (length(tDLLName) - 4) of tDLLName into tShortDLLName
delete last item of pDLLPath
replace "/" with "\" in pDLLPath
if not(_stsIsRegistered(tShortDLLName,pClass)) then
set the hideConsoleWindows to true
get shell("cd" && q(pDLLPath) && "& regsvr32 /s" && tDLLName)
-- Note that calling regsvr32 with the /s param will NOT return
-- any errors back to the command line, so we'll need to
-- check AGAIN to make sure it was registered properly
if not(_stsIsRegistered(tShortDLLName,pClass)) then
return "Error: Could not register DLL."
end if
end if
end stsRegisterDLL
on stsUnregisterDLL pDLLPath,pClass
if pClass ="" then put "Main" into pClass
set the itemDel to "/"
put last item of pDLLPath into tDLLName
put char 1 to (length(tDLLName) - 4) of tDLLName into tShortDLLName
delete last item of pDLLPath
replace "/" with "\" in pDLLPath
if _stsIsRegistered(tShortDLLName,pClass) then
set the hideConsoleWindows to true
get shell("cd" && q(pDLLPath) && "& regsvr32 /u /s" && tDLLName)
-- Note that calling regsvr32 with the /s param will NOT return any
-- errors back to the command line, so we'll need to
-- check AGAIN to make sure it was unregistered properly
if _stsIsRegistered(tShortDLLName,pClass) then
return "Error: Could not unregister DLL."
end if
end if
end stsUnregisterDLL
function _stsIsRegistered pShortDLLName,pClass
-- First check for the key at HKCR\<DLLName>.<Method>
put queryRegistry("HKEY_CLASSES_ROOT\" & pShortDLLName & "." & pClass & "\CLSID\") into tCLSID
put true into tRetVal
if (tCLSID= "bad key") or (tCLSID="") then
put false into tRetVal
else
-- Check CLSID key to make sure
put queryRegistry("HKEY_CLASSES_ROOT\CLSID\" & tCLSID & "\") into tResult
if tResult = "bad key" then
put false into tRetVal
end if
end if
return tRetVal
end _stsIsRegistered
Calling a Non-Rev DLL From Revolution
Now to actually call a Non-Rev DLL from Rev, you need to do six things:
Here's an example of a VB DLL that I wrote that will get the type of a file... the VB function name is called "GetFileType" and calls on the OS to return the type of a file (this is a string like "Microsoft Word document"). This uses the Windows FileSystemObject and looks like this inside VB:
Public Function GetFileType(ByVal pFilePath As String) As String
Dim fso As New Scripting.FileSystemObject
Set tFile = fso.GetFile(pFilePath)
GetFileType = tFile.Type
End Function
The name of the DLL I created from VB was called "STSFile.dll", and the
class I picked to use was "FileMgr".
So with the DLL created, and the class name selected, I created this script in a button in Rev (I had already filled the global gDLLPath with the path to the STSFile.dll file):
global gDLLPath
on mouseUp
answer file "Pick a file:"
if it <> "" then
put it into tFile
stsRegisterDLL gDLLPath,"FileMgr"
answer GetFileType(tFile)
end if
end mouseUp
function GetFileType pPath
replace "/" with "\" in pPath
put "On Error Resume Next" & cr into tVBS
put tVBS & "Dim obj" & cr into tVBS
put tVBS & "Set obj=CreateObject(" & q("STSFile.FileMgr") & ")" & \
cr into tVBS
put tVBS & "tResult = obj.GetFileType(" & q(pPath) & ")" & cr into tVBS
put tVBS & "If Err.Number = 0 Then" & cr into tVBS
put tVBS & "WScript.Echo tResult" & cr into tVBS
put tVBS & "Else" & cr into tVBS
put tVBS & "WScript.Echo" && q("Error:") & " & Err.Number" & cr into tVBS
put tVBS & "End If" into tVBS
return stsDoVBS(tVBS)
end GetFileType
function stsDoVBS pVBScript,pDirectConsole
if pDirectConsole = "" then
put "C:\VBS_temp.vbs" into tVBSPath
put pVBScript into url ("file:" & tVBSPath)
set the hideConsoleWindows to true
get shell("cscript.exe //nologo" && tVBSPath)
else
set the hideConsoleWindows to true
get shell("cscript.exe" && pVBScript)
end if
put it into tResult
if there is a file tVBSPath then
send "delete file" && quote & tVBSPath & quote to me in 1 second
end if
if tResult <> "" then return tResult
end stsDoVBS
function q pWhat
return (quote & pWhat & quote)
end q
The key things to point out are:
put tVBS & "Set obj=CreateObject(" & q("EricTest.Sample") & ")" & cr into tVBS
You can call other third-party Non-Rev DLLs the same way - you just need to know if they are registered, and if so, the name of the function inside the DLL you need, and finally, what class has been picked by the developer for the DLL (which you can find in the Registry as well in the same location and format as I mentioned in (5) above).
Anyway, that's it - it's probably better to create a Rev-specific DLL that you can call directly from inside Rev, but if you don't know how to do that, or you need to access other third-party Non-Rev DLLs, you can use the approach I mention above.
Enjoy!
Ken Ray
Sons of Thunder Software
Posted 11/15/05 by Ken Ray to the Use Revolution List
Updated 7/8/16 by Ken Ray (added missing 'q' function)