06-19-2009 01:49 AM
Hi
I'm working on non-ansi .c and .h libarary files, whick frequently contains Prec_##Type. The meaning of Prec_##Type for example is same as below
char *Type ="Every_2nd_Loop_Sec_W";
the value of Prec_##Type = sprintf(Prec_,Type) = Prec_Every_2nd_Loop_Sec_W //pseudo code.
I'm trying to use this librarys in CVI but hope never to change it. Since CVI does not recongize Prec_##Type, especially the character of "##", firstly of all I need to convert them into like sprintf(Prec_,Type). How can I do it? I think it's kind of precompiled skills.
The precondition:
1, never to change the library files
2, these files would be able to be reused by CVI
Best regards!
Jacky
06-19-2009 08:34 AM
Not sure what your program syntax is exactly, but the ## pre-processor token pasting operator is recognised by CVI and this works:
#define join(x, y) sprintf (str, x##y)
...
char str [256];
...
join ("Prec_", "Every_2nd_Loop_Sec_W"); // str now contains the desired string
JR
07-01-2009 04:50 AM
Hi
Thanks for your reply. Actually, that's not exactly what I want.
Take an exampe below. I want to get FixDefConst (100.0, Percent_W), and there's definition of FixDefConst(). I prefer to translate Min_##TypeName and Prec_##TypeName in pre-compile, or something like that. How can I do it?
typedef unsigned short Percent_W;
#define Prec_Percent_W (100.0 / 4096)
#define Min_Percent_W (0.0)
#define Max_Percent_W (65535 * 100.0 / 4096)
#define FixDefConst(ConstFloat,TypeName) \
((TypeName) FactorRound (((ConstFloat) - Min_##TypeName) / Prec_##TypeName))
...
....
/* Limit final duty cycle to 100% */
LfBSTC_Pct_WasteGateDutyCycle = Min (LfBSTC_Pct_WasteGateDutyCycle,
FixDefConst (100.0, Percent_W));
07-01-2009 05:57 AM
07-01-2009 10:59 AM
Hi
The ultimate purpose in my example is to tranlate Min_##TypeName to Min_Percent_W, but never to assign/assume Min_Percent_W is an integer or string. According to your suggestion on using Join function, the type of Min_##TypeName is a string. Yes, I can use fmt function to convert a string to a number, but that is out of my expectation.
And what I want to do is to simply translate Min_##TypeName to Min_Percent_W before compile/linkage. By the way, in my program there're kinds of ##, like Min_##OldTypeName, Prec_##TypeName. I expect to translate them automatically.
Thanks!
Jacky
07-01-2009 11:12 AM
jacky Wang wrote:
And what I want to do is to simply translate Min_##TypeName to Min_Percent_W before compile/linkage.
But your program already does exactly that! The pre-processor substitutes the correct text just before the compile step. I must be misunderstanding something. Are you trying to avoid using the #define Min_Percent_W statement?
JR
07-01-2009 07:36 PM
Hi
I think I didn't explain my question clearly.
Attached is the real head files I reuse. I include them in CVI and use FixDefConst(5.0, Every_2nd_Loop_Sec_W). I don't want to modify these two head files, which contains ##. However, if there's no pre-compile treatment on them, error will be given when compiling. So I'm trying to find a way to translate ## before compile.
#include <cvirte.h>
#include "type_math.h"
#include "type_def.h"
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
FixDefConst(5.0, Every_2nd_Loop_Sec_W);
return 0;
}
07-02-2009 03:08 AM
If you can attach the .h files to your next post, this might help us to see what the compiler doesn't like.
JR
07-02-2009 03:47 AM
ok, let's try to clarify.
the ## operator is treated by the preprocessor, which means it operates before the compilation. it is named the token-pasting operator: its purpose is to take whatever text is in left and right and make a complete token out of that. remember that the token is formed at the preprocessing: the token does not have a type at all, it is only text pasted in the source code, in the same way #define works.
jr_2005 gave an example, which was indeed using strings (note how the arguments to join() are surrounded by ""):
#define join(x, y) sprintf (str, x##y)
char str [256];
join ("Prec_", "Every_2nd_Loop_Sec_W");
but the example works also for variable names:
#define int_min -32768 // define some values
#define int_max 32768
#define float_min -1e99
#define float_max 1e99
// the next line defines a macro which will allow to link the type name to the values defined
#define min( type ) type##_min
#define max( type ) type##_max
int main()
{
int value;
// how it works: when you type "min(int)" in your source code, the preprocessor will perform
// a replacement: copy the source text of the argument, paste it and append the _min
value = min( int );
// so the above line is replaced by the preprocessor by this code:
value = int_min;
// int_min is a #define, so ultimately the preprocessor replaces it by its defined value
value = -32768;
// this last line is what is effectively passed to the compiler.
printf( "the minimum value for type int is:%i\n", min( int ) );
}
token pasting is done before compiling, thus cannot be used at runtime. the following example will not work at all:
#define int_min -32768 // define some values
#define int_max 32768
#define min( type ) type##_min
int main()
{
char line[256];
printf( "enter a type name: " );
gets( line );
printf( "the minimum value for type %s is:%i\n", line, min( line ) );
// this does not work because min(line) is replaced before compiling by line_min, which is not defined.
}
07-02-2009 07:32 AM
Find attached.
Thanks!
Jacky