Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a DLL (or VB6) file from VBScript

Tags:

dll

vb6

vbscript

I'm trying to use VBScript to access functions within a VBA file (or a DLL). I'm quite a bit out of my depth, and I don't normally use either of these languages, so I'll explain the situation, in case there's a better solution.

I have an instrument that has an internal VBScript-like window (it has some features not found in VBScript, such as an "Include...End Include" statement) that can be used to automate instrument operation, and I'm trying to use this in combination with a camera. For the camera, the company supplied VB (atmcd32d.bas) and C++ (atmcd32d.cpp) files containing all the necessary functions (e.g., GetTemperature, StartAcquisition, etc.) for communicating with a DLL file (atmcd32d.dll), which I assume sends commands to the camera. If I were using C++ or VBA, I assume I could directly include those files, which would give my code access to the commands needed to control the camera. However, the scripting language used by the software of the main instrument is closest to VBScript. The script lets me include the file if I change it to .txt, but of course it fails when it gets to commands like "Attribute", "ENUM", and "Declare Function", which aren't part of VBScript.

I was wondering, first, if there's a better way to run the .bas file.

Alternatively, I thought I could try to translate the functions that I need from the .bas file, so I could communicate with the DLL from VBScript. This changes one problem into 2 problems. The first problem it creates is the translation, and I'm not sure if that's a realistic approach. Since it's a 750 line file, I wanted to ask others first.

The second problem is how to communicate with the DLL. I found a page on using VBScript to communicate with a DLL: How to call C# DLL function from VBScript

And I tried to use that approach. For my case, I assumed that the DLL is already registered, since it was installed along with the camera software, so I just need to use:

Set obj = CreateObject("C:\MyPath\atmcd32d.dll")

to get access to the camera functions. But if I run a script with only that line, I get the message "ActiveX component can't create object". Does this mean the DLL isn't registered? Or did I make some other error?

I apologize for the convoluted question, but given how far I've gotten in over my head already, I figured I should ask for help before I dug too deeply in the wrong direction.

like image 890
Matt Avatar asked Mar 19 '26 11:03

Matt


1 Answers

The impression I get from what seems to be the documentation for your Andor camera (https://neurophysics.ucsd.edu/Manuals/Andor%20Technology/Andor_Software_Development_Kit.pdf) is that the DLL is not going to be directly accessible from VBScript.

The docs say this:

When building you own projects you must include the file ATMCD32D.BAS. This file contains the Andor SDK function prototypes for interfacing with the dynamic link library ATMCD32D.DLL

They are not referring to VBScript here, but probably a more 'standard' version of BASIC such as VB.NET or the now quite old VB6 ("classic" VB). Those languages have features to directly call functions in a DLL such as theirs.

VBSCript on the other hand apparently only has the ability to access external DLLs which support the COM specifications. One way to think of COM is that it is a standard way of making objects (or classes) accessible from a DLL - but not just plain functions like you would get from a language like C for instance. However their DLL doesn't seem like it would directly support COM. (But to double check this, see https://stackoverflow.com/a/3011424/3195477 or https://stackoverflow.com/a/49920874/3195477).

So what you will need to do is write your own code that will act as a wrapper around the functions in the Andor DLL. That wrapper DLL needs to provide COM classes which in turn call the actual Andor DLL functions. This wrapper could be written in any language that is capable of producing a COM-visible DLL. A suggestion is that you use VB.NET for this, because that might be the simplest route to incorporate the ATMCD32D.BAS file. The syntax of that file is likely to be fully compatible with VB.NET (can't verify that myself, however).

Visual Studio is more than capable of producing such a DLL for you, and will also be able to use .NET tools to more or less automatically generate the COM layer that you will need. In a VB.NET project you need to create (at least) one class which you will call from VBScript. That class should have functions corresponding to whatever functions in the Andor DLL you need to use. You don't have to include them all - in fact as a first step I would just do the most basic thing you can think of as a proof of concept to confirm all the "wiring" is correct. The class functions could literally just match the names & parameters of the DLL functions, or you could add some additional logic as needed.

So in summary, here are the steps I would follow:

  1. Run Visual Studio
  2. Create a new VB.NET class library project
  3. In the project properties, make sure it is set to register as COM-visible (I forget the exact wording of this option)
  4. Add a class, let's say WrapperClass
  5. Probably you can copy the contents of the .BAS file into this class. It should contain a bunch of DECLARE FUNCTION statements, I expect.
  6. Add public SUBs or FUNCTIONs to your class which just call the DECLAREed functions.
  7. Make sure the class has the <COMVisible(true)> attribute applied to it, and I would also use <ClassInterface(ClassInterfaceType.AutoDual)> for this.
  8. Compile the class library project in Visual Studio. If everything is setup correctly it will also register the DLL it creates for you.
  9. Probably you will need to copy the Andor DLL to the same location as your wrapper DLL (project\bin\debug\ folder typically)
  10. In VBScript you can then do things like:
Set obj = CreateObject("WrapperClass")   
Call obj.WrapperFunction1 ...

(I tend to use C# instead of VB.NET but I think the strategy above is correct, these details would be mostly the same.)

Be prepared that it may take some time to work out any kinks in your implementation. What you have to do with COM is not too complex but there are plenty of small pitfalls. Also this assumes a lot about the proprietary nature of the VBScript environment that you are using.

If you are not running Visual Studio on the same PC which will be running the VBScript program then you will need to do some extra steps to manually copy & then register the wrapper DLL on that PC (so that CreateObject will work). It is also conceivable in this circumstance that a .NET update may be needed. If you can find out what version of .NET is already on that PC I would just set the wrapper DLL to compile against said version; it probably won't actually matter for the code you need to write.

like image 68
StayOnTarget Avatar answered Mar 22 '26 13:03

StayOnTarget