comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Win32 jacket routines between IDL and third-party DLL
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Win32 jacket routines between IDL and third-party DLL [message #13895] Wed, 06 January 1999 00:00
rivers is currently offline  rivers
Messages: 228
Registered: March 1991
Senior Member
In article <76vl1k$h41$1@willow.cc.kcl.ac.uk>, nra@maxwell.ph.kcl.ac.uk (Nigel
Arnot) writes:
> I have very little programming experience in the Win32 environment, so
> apologies if this is a trivial question.
>
> The problem I'm looking at is that a colleague wants to use an IDL front-end
> program to control a CAMAC crate. The crate controller comes with a set of
> C-callable routines in the form of a DLL, but the arguments expected aren't
> in the form that IDL's CALL_EXTERNAL will generate.
>
> So, what's needed are jacket routines that accept arguments from IDL, and then
> generate calls to the CAMAC controller routines.
>
> Is it straightforward to write a DLL called from IDL that in turn calls
> another DLL, and where do I look up the details?

Yes, this is easy. You are effectively doing this whenever your C programs
call any of the C runtime library routines, or call the WIN32 API routines.

> If anyone has done something like this already, I'd much appreciate a peek at
> the code!

I have done lots of coding like that. I control CAMAC crates from IDL under
VMS, and I am about to do it under Windows NT, using the Kinetic Systems crate
controller and their DLL.

The only code I have right now looks quite complex, because I have written it
with macros which allow it to work under both IDL and PV-WAVE, and under VMS,
Unix, and Windows. All of these systems pass their arguments (especially
strings) differently.

Here is the beginning of that file:

#include <tsDefs.h>
#include <cadef.h>
#include <ezca.h>

#include <Ezca.h>
#define OK 0
#undef ERROR
#define ERROR -1
extern struct caGlobals CA;

/* ezcaIDL.c
*
* This file is an interface layer between IDL/PV-WAVE and EZCA. It mainly
* just converts parameter passing from the IDL/PV-WAVE mechanisms
* (most parameters passed by reference) to the mechanism required by EZCA.
* For a few the functions which are not supplied by EZCA this routine actually
* does the work, using the ezcaPvToChid to fetch the channel descriptor.
*
* Author: Mark Rivers
* Date: June 28, 1995
*/

/* The following macros allow for the differences in the way PV-WAVE and
* IDL pass character strings. PV-WAVE passes the address of the address
* of the string in argp[]. IDL passes the address of a string descriptor
* structure, which contains the address of the string as one of its elements */
#ifdef IDL
typedef struct {
unsigned short length;
short type;
char *address;
} IDL_STR_DESCR;
#define STRARG IDL_STR_DESCR
#define STRADDR(s) s->address
#define STRFIXLEN(s) s->length = strlen(s->address)
static char* str_array_addr[1000];
#define BUILD_STR_ARRAY(len, s) for (i=0; i<len; i++) str_array_addr[i]=s[i].address
#define STR_ARRAY_ADDR(s) str_array_addr

#else /*(PV-WAVE)*/
#define STRARG char*
#define STRADDR(s) *s
#define STRFIXLEN(s) (*s)[strlen(*s)] = (char) 32
#define BUILD_STR_ARRAY(len, s)
#define STR_ARRAY_ADDR(s) s
#endif

/* The following macros allow this source file to be used with
PV-WAVE and IDL on both Unix and VMS platforms. The difference
is that on VMS platforms arguments are passed directly
(by reference), while on Unix they are passed by the (argc, argp)
mechanism. These macros also simplify the code for each routine. */
#if defined (VMS)
# define WAVE_HEADER0(ftype, fname)\
ftype fname() {
# define WAVE_HEADER1(ftype, fname, type1, arg1)\
ftype fname(type1 *arg1) {
# define WAVE_HEADER2(ftype, fname, type1, arg1, type2, arg2)\
ftype fname(type1 *arg1, type2 *arg2) {
# define WAVE_HEADER3(ftype, fname, type1, arg1, type2, arg2, type3, arg3)\
ftype fname(type1 *arg1, type2 *arg2, type3 *arg3) {
# define WAVE_HEADER4(ftype, fname, type1, arg1, type2, arg2, type3, arg3, type4, arg4)\
ftype fname(type1 *arg1, type2 *arg2, type3 *arg3, type4 *arg4) {
# define WAVE_HEADER5(ftype, fname, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5)\
ftype fname(type1 *arg1, type2 *arg2, type3 *arg3, type4 *arg4, type5 *arg5) {

#else
# define WAVE_HEADER0(ftype, fname)\
ftype fname(argc, argp)\
int argc;\
void *argp[];\
{
# define WAVE_HEADER1(ftype, fname, type1, arg1)\
ftype fname(argc, argp)\
int argc;\
void *argp[];\
{\
type1 *arg1 = (type1 *) argp[0];
# define WAVE_HEADER2(ftype, fname, type1, arg1, type2, arg2)\
ftype fname(argc, argp)\
int argc;\
void *argp[];\
{\
type1 *arg1 = (type1 *) argp[0];\
type2 *arg2 = (type2 *) argp[1];
# define WAVE_HEADER3(ftype, fname, type1, arg1, type2, arg2, type3, arg3)\
ftype fname(argc, argp)\
int argc;\
void *argp[];\
{\
type1 *arg1 = (type1 *) argp[0];\
type2 *arg2 = (type2 *) argp[1];\
type3 *arg3 = (type3 *) argp[2];
# define WAVE_HEADER4(ftype, fname, type1, arg1, type2, arg2, type3, arg3, type4, arg4)\
ftype fname(argc, argp)\
int argc;\
void *argp[];\
{\
type1 *arg1 = (type1 *) argp[0];\
type2 *arg2 = (type2 *) argp[1];\
type3 *arg3 = (type3 *) argp[2];\
type4 *arg4 = (type4 *) argp[3];
# define WAVE_HEADER5(ftype, fname, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5)\
ftype fname(argc, argp)\
int argc;\
void *argp[];\
{\
type1 *arg1 = (type1 *) argp[0];\
type2 *arg2 = (type2 *) argp[1];\
type3 *arg3 = (type3 *) argp[2];\
type4 *arg4 = (type4 *) argp[3];\
type5 *arg5 = (type5 *) argp[4];
#endif


WAVE_HEADER4(int, ezcaIDLGet, STRARG, pvname, char, type, int, nelem, void, buff)
return(ezcaGet(STRADDR(pvname), *type, *nelem, buff));
}

WAVE_HEADER3(int, ezcaIDLGetControlLimits, STRARG, pvname, double, low, double, high)
return(ezcaGetControlLimits(STRADDR(pvname), low, high));
}

WAVE_HEADER3(int, ezcaIDLGetGraphicLimits, STRARG, pvname, double, low, double, high)
return(ezcaGetGraphicLimits(STRADDR(pvname), low, high));
}

WAVE_HEADER2(int, ezcaIDLGetPrecision, STRARG, pvname, short, precision)
return(ezcaGetPrecision(STRADDR(pvname), precision));
}

WAVE_HEADER4(int, ezcaIDLGetStatus, STRARG, pvname, TS_STAMP, timestamp, short, status, short, severity)
return(ezcaGetStatus(STRADDR(pvname), timestamp, status, severity));
}

WAVE_HEADER2(int, ezcaIDLGetUnits, STRARG, pvname, char, units)
return(ezcaGetUnits(STRADDR(pvname), units));
}

WAVE_HEADER1(int, ezcaIDLPerror, char, prefix)
ezcaPerror(prefix);
return EZCA_OK;
}

WAVE_HEADER2(int, ezcaIDLGetErrorString, char, prefix, char, err_string)
int status;
char *buff;

status = ezcaGetErrorString(prefix, &buff);
strcpy(err_string, buff);
ezcaFree((void *)buff);
return(status);
}

WAVE_HEADER4(int, ezcaIDLPut, STRARG, pvname, char, type, int, nelem, void, buff)
return(ezcaPut(STRADDR(pvname), *type, *nelem, buff));
}

WAVE_HEADER3(int, ezcaIDLGetCountAndType, STRARG, pvname, int, count, char, type)
int status;
chid *chid;

status = ezcaPvToChid(STRADDR(pvname), &chid);
if (status != EZCA_OK) return(status);
*count = ca_element_count(*chid);
*type = ca_field_type(*chid);
return EZCA_OK;
}

WAVE_HEADER2(int, ezcaIDLSetMonitor, STRARG, pvname, char, type)
return(ezcaSetMonitor(STRADDR(pvname), *type));
}

WAVE_HEADER2(int, ezcaIDLClearMonitor, STRARG, pvname, char, type)
return(ezcaClearMonitor(STRADDR(pvname), *type));
}

WAVE_HEADER2(int, ezcaIDLNewMonitorValue, STRARG, pvname, char, type)
return(ezcaNewMonitorValue(STRADDR(pvname), *type));
}

WAVE_HEADER1(int, ezcaIDLSetTimeout, float, sec)
return(ezcaSetTimeout(*sec));
}

WAVE_HEADER1(int, ezcaIDLSetRetryCount, int, retry)
return(ezcaSetRetryCount(*retry));
}

WAVE_HEADER1(int, ezcaIDLGetTimeout, float, timeout)
*timeout = ezcaGetTimeout();
return EZCA_OK;
}

WAVE_HEADER1(int, ezcaIDLGetRetryCount, int, retrycount)
*retrycount = ezcaGetRetryCount();
return EZCA_OK;
}

WAVE_HEADER2(int, ezcaIDLEndGroupWithReport, int, nvals, int, status)
int rc, nrcs;
int *rcs;
int i;

rc = ezcaEndGroupWithReport(&rcs, &nrcs);
if (nrcs > *nvals) nrcs = *nvals;
if (*nvals > nrcs) *nvals = nrcs;
for (i=0; i<*nvals; i++) status[i] = rcs[i];
ezcaFree((void *) rcs);
return(rc);
}
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Getting MPEG routines to write from 24-bit display.
Next Topic: formating error in Re: Here is some code to call IDL or PV-WAVE from C.

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Sat Oct 11 14:35:28 PDT 2025

Total time taken to generate the page: 0.16506 seconds