Overview
The following sections illustrate how to make a Direct Entry application. The code fragments are written in C, but the same techniques shown using C can also be applied to other programming languages.
You can run a Win32s application using the 16-bit GPIB software for Windows 3.
The use of direct entry means that the programs take the responsibility of accessing the 32-bit GPIB DLL. Direct access to the 32-bit GPIB DLL is accomplished by loading the DLL when the program is ready to use it (using LoadLibrary), obtaining addresses of the global variables and functions that the program needs to use (using GetProcAddress), and finally, unloading the DLL (using FreeLibrary) before exiting.
You can directly access the gpib-32.dll from any programming environment that allows you to request addresses of variables and functions that a DLL exports. The gpib-32.dll exports pointers to each of the global variables and all of the NI-488 and NI-488.2 calls.
Table of Contents
- Win32s API Information
- Items to Include in Your Direct Entry GPIB Application
- Casting the Function Pointers
- Using LoadLibrary Function to Load gpib-32.dll
- Using GetProcAddress Function to Get Pointers to Functions and Global Variables
- Dereferencing the Pointers to Functions and Global Variables
- Using FreeLibrary Function to Unload gpib-32.dll
- Borland C/C++ Issue
- Microsoft Visual C++ Issue
- Watcom C/C++ Issues
Win32s API Information
You must have the Win32s Application Programming Interface (API) installed on your Windows 3.x system. The Win32s API is a subset of the Win32 API. The gpib-32.dll must also be installed on your system. This DLL comes with the latest GPIB software for Windows 3.X.
See Also:
NI-488.2 Software for Windows 3.X
Items to Include in Your Direct Entry GPIB Application
Your application needs to include the header files, windows.h and decl-32.h. The 32-bit GPIB DLL exports pointers to the global variables and all of the NI-488.2 functions and subroutines. Pointers to the global variables (ibsta, iberr, ibcnt, and ibcntl) are accessible through these exported variables:
- int *user_ibsta;
- int *user_iberr;
- int *user_ibcnt;
- long *user_ibcntl;
At the beginning of your application, make sure that the following lines are included:
/* With C++ compiler, this prevents name-mangling */
#ifdef __cplusplus
extern "C" {
#endif
/* Necessary Header Files */
#include <windows.h>
#include "decl-32.h"
#ifdef __cplusplus
}
#endif
/* Pointers to NI-488.2 global status variables */
int *Pibsta;
int *Piberr;
int *Pibcnt;
long *Pibcntl;
/* Global variable for the handle to the loaded GPIB-32.DLL */
HINSTANCE Gpib32Lib = NULL;Casting the Function Pointers
Except for the functions explicitly listed below, all of the NI-488.2 function and subroutine names are exported by the 32-bit GPIB DLL. What this means is that to use direct entry to access a particular function (for example, ibwrt) all you need to do to get a pointer to the exported function is to call GetProcAddress passing the name of the function (for example, ibwrt) as a parameter. The parameters that you use when you invoke the function are identical to those described in the Format C section for the ibwrt command in the NI-488.2 Function Reference Manual for Windows.
There are a few functions that the 32-bit GPIB DLL exports with slightly different names. Here is a list of those functions:
- ibbna
- ibfind
- ibrdf
- ibwrtf
These functions all require an argument that is a name. ibbna requires a board name (for example, "gpib0"), ibfind requires a board or device name, and ibrdf and ibwrtf take a file name. Since Windows 2000/NT supports both normal, 8-bit characters and Unicode, 16-bit wide characters, gpib-32.dll exports two versions of each of these functions. An ASCII version is for 8-bit characters (ibbnaA, ibfindA, ibrdA, ibwrtA) and a "wide" version for 16-bit characters (ibbnaW, ibfindW, ibrdW, ibwrtW). Windows 3 does not support wide characters. So the only valid one to use is the 8-bit ASCII version.To access any of these four functions in your application, you must use the correct function name when calling GetProcAddress. For Windows 3 applications, use the 8-bit ASCII versions named ibbnaA, ibfindA, ibrdfA, and ibwrtfA.
The prototypes for each function can be found in the Function Reference Manual. For functions that return an integer value, like ibdev, the pointer to the function needs to be cast as:
int (__stdcall *Pname)
where *Pname is the name of the pointer to the function. For functions (i.e., the 488.2 calls) that do not return a value, the pointer to the function needs to be cast as:
void (__stdcall *Pname)
where *Pname is the name of the pointer to the function. They are followed by the function's list of parameters as described in the Function Reference Manual. Below is an example of how to cast the function pointer and how the parameter list is set up for ibdev and ibonl functions:
int (__stdcall *Pibdev)(int ud, int pad, int sad, int tmo, int eot, int eos);
int (__stdcall *Pibonl)(int ud, int v);See Also:
NI-488.2 Function Reference Manual for Windows
Using LoadLibrary Function to Load gpib-32.dll
Within your application, you need to load the gpib-32.dll library. The example below shows you how to call the LoadLibrary function along with a way to handle an error:
Gpib32Lib = LoadLibrary("gpib-32.dll");
if (!Gpib32Lib)
return FALSE;
Using GetProcAddress Function to Get Pointers to Functions and Global Variables
Next, your Win32s application needs to use GetProcAddress to get the addresses of the global status variables and functions you need to use. The following code fragment illustrates how to get the addresses of the pointers to the status variables and any functions your application needs to use:
Pibsta = (int *) GetProcAddress(Gpib32Lib, (LPSTR)"user_ibsta");
Piberr = (int *) GetProcAddress(Gpib32Lib, (LPSTR)"user_iberr");
Pibcntl = (long *) GetProcAddress(Gpib32Lib, (LPSTR)"user_ibcntl");
Pibdev = (int (__stdcall *) (int, int, int, int, int, int)) GetProcAddress(Gpib32Lib, (LPCSTR)"ibdev");
Pibonl = (int (__stdcall *) (int, int))GetProcAddress(Gpib32Lib, (LPCSTR)"ibonl");
If GetProcAddress fails, it returns a NULL pointer. The following code fragment illustrates how to verify that none of the calls to GetProcAddress failed:
if ((Pibsta == NULL) ||
(Piberr == NULL) ||
(Pibcntl == NULL) ||
(Pibdev == NULL) ||
(Pibonl == NULL))
{
FreeLibrary(Gpib32Lib);
Gpib32Lib = NULL;
return FALSE;
}
else
return TRUE;
Dereferencing the Pointers to Functions and Global Variables
Your Win32s application needs to dereference the pointer to access either the status variables or functions. The following code illustrates how to call a function and access the status variable from within your application:
dvm = (*Pibdev) (0, 1, 0, T10s, 1, 0);
if (*Pibsta & ERR) Then
printf("Call failed");
(*Pibonl) (dvm, 0);
Using FreeLibrary Function to Unload gpib-32.dll
Upon completion of your program, free the library with the following:
FreeLibrary(Gpib32Lib);
Borland C/C++ Issue
The 32-bit Borland C/C++, version 4.x, will run in Windows 3.x, but not Borland C/C++, version 5.0 and higher, nor Borland C++ Builder.
Microsoft Visual C++ Issue
The 32-bit Microsoft Visual C++ (version 2.0 and higher), is NOT supported in Windows 3.x.
Watcom C/C++ Issues
Information about Win32s or Win32 programming is documented in the Watcom C/C++ manuals and online help starting with version 9.5.
The sample program uses some keywords that are used by the Windows NT portion of the Watcom C/C++ compiler, so the PATH, INCLUDE, and LIB statements in the autoexec.bat file need to include references to Watcom's NT directories also. The examples below show you how to set up your autoexec.bat file. All instances of <watcom> refers to the path where your Watcom C/C++ compiler installed (usually c:\watcom).
- To set up the PATH statement, you need to add the Watcom directories. You can add this information by using either one of two techniques. The first technique is to simply add the following list of directories to the end of your existing PATH statement. Below is the list of the necessary directories:
<watcom>\bin;<watcom>\binb;<watcom>\binw;<watcom>\binnt;
Or you can append the additional set of directories to your existing PATH statement by using %PATH%. Directly underneath your current PATH statement, add the following line:
PATH=%PATH%;<watcom>\bin;<watcom>\binb;<watcom>\binw;<watcom>\binnt;
- To set up the INCLUDE statement, add the line as shown below:
SET INCLUDE=<watcom>\h;<watcom>\h\NT;
- To set up the LIB statement, add the line as shown below:
SET LIB=<watcom>\LIB386\NT;<watcom>\LIB386;
Related Links:
GPIB Sample Programs
Reader Comments | Submit a comment »
Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).
