Using Non-Rev DLLs With Revolution |
(Windows Only)
|
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:
The name of the DLL I created from VB was called "STSFile.dll", and the class I picked to use was "FileMgr".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
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
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