LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

runtime type checking

 

I have a variable argument function:

 

int SetAttribute(object obj, int attrib, ...);

 

I want to check the type a user puts to the variable list at runtime. CVI itself can check the type put into SetCtrlAttribute(int panel, int ctrl, ..). Is it possible to check the type within a va_list at runtime?

 

Thanks in advance.

 

 

 

0 Kudos
Message 1 of 8
(5,267 Views)

Hi,

 

yould you please post more details about what you want to do? I do not really understand your question. Do you want to specify a data type at run-time, because at compliation time this is not known? 

 

Furthermore, where does the SetAttribute function comes from? It is not a standard CVI function I believe, 

 

 

Best Regards, Fabian

0 Kudos
Message 2 of 8
(5,235 Views)

 

This is standard CVI:

int CVIFUNC_C SetCtrlAttribute(int panel, int control, int attribute, ...);

 

any attributes entered into SetCtrlAttribute() will be type checked by CVI. If you put a wrong type to the attribute value (the "..." parameter)  you will get a runtime error message.

 

This is NOT CVI:

typedef struct anonym* Object;

int Object_SetAttribute(Object mvalue, int attrib, ...)

{

   va_list args;

   va_start(args,attrib);

 

   // This is actualy a cast to int but you can not be sure if the parameter entered in "..." is realy int.

   // CVI can type check here. With RTTI (Runtime type checking) one can check if the attribute is realy of type int.

   // If CVI does it internaly, can a CVI user does it too?

   int x = va_arg(args,int);

   

  va_end(args);

 

  return x;

}

 

The compiler will not complain if you do:

Object_SetAttribute(object, 123,"ABC");

 

I would like to check the type of a parameter from a variable parameter list before I extract the parameter from the list. This is very helpful to avoid bugs and saves time when debugging.

 

I hope this explains my problem.

0 Kudos
Message 3 of 8
(5,229 Views)

Hi, 

 

the CVI Function works in the following way. see help documentation:

http://zone.ni.com/reference/en-XX/help/370051T-01/cvi/uiref/cvigetctrlattribute/ 

it is a void pointer.

 

you can also created a variable argument list:

http://www.ni.com/example/29450/en/

 

the only way how to do it would be via such a pointer and realize it on the same way

 

Best Regards, Fabian

0 Kudos
Message 4 of 8
(5,044 Views)

I remember to have found an example which I can't locate at the moment that passes both the variable value and type to the variable-argument function. The structure is as follows:

 

// Typo of parameters passed to the function ("stdarg.h")
#define	INTPRM		1	// Integer
#define	DBLPRM		2	// Double
#define CHRPRM		3	// Char
#define STRPRM		4	// Structure

typedef struct {
	double	Dprm;
	int	Iprm;
	char	Cprm[16];
} dummy;

void VarParmFunc (int *parms, ...);

// Button callback which uses the variable-argument function int CVICALLBACK varFunc (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int cnt = 0; int Iprm; double Dprm; char Cprm[16]; dummy *dd = NULL; if (event != EVENT_COMMIT) return 0;
// Read values and fill-in type array GetCtrlVal (panel, PANEL_parm1, &Dprm); parms[cnt++] = DBLPRM; GetCtrlVal (panel, PANEL_parm2, &Iprm); parms[cnt++] = INTPRM; GetCtrlVal (panel, PANEL_parm3, Cprm); parms[cnt++] = CHRPRM; dd = malloc (sizeof (dummy)); GetCtrlVal (panel, PANEL_Field1, &dd->Dprm); GetCtrlVal (panel, PANEL_Field2, &dd->Iprm); GetCtrlVal (panel, PANEL_Field3, dd->Cprm); parms[cnt++] = STRPRM; parms[cnt++] = 0; VarParmFunc (parms, Dprm, Iprm, Cprm, dd); if (dd) free (dd); return 0; } // Variable-arguments function void VarParmFunc (int *parms, ...) // This simply echos received parameters { int cnt = 0; char type, msg[256]; dummy *dd; va_list ap; if (!parms) goto Exit; // Initialize variable-argument list handling va_start (ap, parms); strcpy (msg, "Received parms:\n"); // List parameters while ((type = *parms++) != 0) { switch (type) { case INTPRM: sprintf (msg, "%s\n Integer: %d", msg, va_arg (ap, int)); cnt++; break; case DBLPRM: sprintf (msg, "%s\n Double %.2f", msg, va_arg (ap, double)); cnt++; break; case CHRPRM: sprintf (msg, "%s\n String: %s", msg, va_arg (ap, char *)); cnt++; break; case STRPRM: dd = va_arg (ap, dummy *); sprintf (msg, "%s\n Struct:\n Double: %.2f\n Integer: %d\n String: %s", msg, dd->Dprm, dd->Iprm, dd->Cprm); cnt++; break; } } ResetTextBox (mainH, PANEL_res, msg); Exit: sprintf (msg, "%d parameters received", cnt); MessagePopup ("Variable params", msg); Error: // End variable arguments handling va_end (ap); return; }

 

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 8
(5,035 Views)

An alternative can be to use variants instead of simple variables: as you may know, variants can store different types of data and can be queried for the type store in them by means of CA_VariantGetType () function. This can simplify type checking inside your function, at the cost of a considerably more complex data handling.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 8
(5,034 Views)

The link above contains an ' ':

http://zone.ni.com/reference/en-XX/help/370051T-01/cvi/uiref/cvigetctrlattribute/

 

The help page does not tell anything about RTTI.

 

I copied the SetCtrlAttribute() function from the header of CVI2013. There is no void*. See userint.h.

And you can try to use a wrong type to the attribute setter of a control and you will get a runtime error message.

 

Yes and I did write an example already for using va_list. Another example dosen't help.

0 Kudos
Message 7 of 8
(5,028 Views)

Thanks Roberto for your Tips. I was thinking on that already but I can not ask my users to striktly insert a correct type into the parameter list.

The probability of using a wrong type will not change with that aproach. I have to implement it without RTTI.

May be NI will publish a solution to that once. The best solution would be a RTTI implementation to the compiler. I don't know the effort to spend in devloping RTTI for CVI but that would improve stability to CVI generated products.

 

Regards

 

Andrej

0 Kudos
Message 8 of 8
(5,026 Views)