ni.com is currently undergoing scheduled maintenance.

Some services may be unavailable at this time. Please contact us for help or try again later.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Enum with Call Library/Activex

Clearly enums are necessary for interfacing with external code; it makes a
lot more sense to specify enumerated value RES_MODE_1024 than some opaque
constant 0xF573 required by the external library.

However since you cannt specify the value of an enum like in C/C++, my
workaround is to use the enum to index an array of values. This is not only
messy, but also problematic. I have very little control over the values
which the enum take. Adding a new enumerated value may map values in
unpredictable ways.

Is there an easier solution that I'm missing? Or will a change exist in LV7?
Normally LV is great for interfacing with external code but the primitive
enum support is a serious problem.

-joey
0 Kudos
Message 1 of 6
(3,637 Views)
First thing, make the enums typedefs so changes are always propagated to everywhere the enum is used. Second, in terms of mapping, the ease with which you can do it depends on the enum values. If they are numerically sequential in value, converting the input enum to an integer and adding an offset will do the translation. If the numeric value of the enum is nonsequential the easiest solution is to create a case structure with one frame for each value. Then put constants in the cases related to each enum value. Mike... PS: I don't see anything that needs fixing.

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 2 of 6
(3,637 Views)
Joey,

I agree that this functionality is missing from current versions of LabVIEW. However, Mike is right in his thinking. Also, a suggestion has been put in, so look for it in a future version of LabVIEW.

Randy Hoskin
Applications Engineer
National Instruments
http://www.ni.com/ask
0 Kudos
Message 3 of 6
(3,637 Views)
Yes, I of course use the control typedefs since that most closely models C
behavior.

Indeed the sequential mapping (offset + enum * multiplier) is a special
case. Sometimes that works, but for communication (as originally described)
you should expect sparse non-sequential mappings. Instruments or libraries
frequently use some bit-pattern or bit-position to represent a setting.
Rather than wire up a numeric constant "42" it makes sense to present an
enumerated set of possible choices.

I believe the case statement you propose is similar in spirit to indexing an
array which I proposed in my previous email. The case statement has an
advantage that if an enumerated value changes (by adding some additional
item) the case statement will still map to the intended output value, where
the indexes to an array might change. This is also an inherent disadvantage
because specifying outputs for a large number of enumerated values requires
a lot of clicking, and the case structure graphically exposes only one
output at a time instead of a single table with every mapped value. I don't
see a clear winner for easiest solution.

Neither solution easily autonumbers enumerations when a value is unspecified
(C does this), and neither is a direct mapping. Every time the enum is used,
a piece of code must follow to determine the actual mapped value. An enum
should be a human readable representation of a value; but at a given point
in the code this could be the LV index (0,1,2..), or its output after the
mapping function (42,0x7A,...). By adding confusion, was there really much
gain above using a numeric constant in the first place?

So no, I disagree. This does need re-engineering because it makes
communication unnecessarily difficult. At lower levels the enumerated values
are going to be sparse, non-sequential bit-patterns. Is there any reason to
prevent the programmer from representing them directly just like in C?

-joey

"mikeporter" wrote in message
news:506500000005000000A2DC0000-1042324653000@exchange.ni.com...
> First thing, make the enums typedefs so changes are always propagated
> to everywhere the enum is used. Second, in terms of mapping, the ease
> with which you can do it depends on the enum values. If they are
> numerically sequential in value, converting the input enum to an
> integer and adding an offset will do the translation. If the numeric
> value of the enum is nonsequential the easiest solution is to create a
> case structure with one frame for each value. Then put constants in
> the cases related to each enum value. Mike... PS: I don't see
> anything that needs fixing.
0 Kudos
Message 4 of 6
(3,637 Views)
> Indeed the sequential mapping (offset + enum * multiplier) is a special
> case. Sometimes that works, but for communication (as originally described)
> you should expect sparse non-sequential mappings. Instruments or libraries
> frequently use some bit-pattern or bit-position to represent a setting.
> Rather than wire up a numeric constant "42" it makes sense to present an
> enumerated set of possible choices.
>
....
> So no, I disagree. This does need re-engineering because it makes
> communication unnecessarily difficult. At lower levels the enumerated values
> are going to be sparse, non-sequential bit-patterns. Is there any reason to
> prevent the programmer from representing them directly just like in C?
>

There is a bit of a philosophical difference in how these things should
be exposed to the user/programmer. LV has the more pure form of
enumeration, more like the pascal language. C on the otherhand has
defines and enums that allow just about anything. Which is correct?
Again, it is a matter of philosophy.

The philosophy that LV prefers is to use nice numbers in the interface
to the driver software and hide the specific bit patterns and numbers
inside the driver SW. Unfortunately, this isn't universal, even NI
driver SW will sometimes expose odd bit patterns and such. But, it is
possible and recommended that you not scatter the constants throughout
your program, and instead isolate the constants in as few locations as
possible.

For instance, if you are communicating to a DLL, ideally, you do not
drop DLL nodes throughout your program and again and again configure
them to call into the functions that the DLL exposes. Instead, each
time you need to call a specific function in the DLL, make a small
wrapper subVI with the configured DLL node, and exposing the parameters
which you want to be able to change and using constants for others.
This is also the best place to smooth over the odd bit patterns and give
them a strict enumeration type. Then throughout your application, use
the nicer wrapper subVI with its nicer types, its icon, description, its
debugging abilities, etc.

As mentioned in another posting, the capability to do arbitrarily valued
rings or enumerations will likely show up in LV in future releases, but
this technique of wrapping external interfaces to give them a nicer and
more reusable LV interface is still a useful tool to avoid spreading
interface specifics throughout your code.

Greg McKaskle
0 Kudos
Message 5 of 6
(3,637 Views)
"Greg McKaskle" wrote in message
news:gmckaskle-CBF048.08403520032003@newsr1.texas.rr.com...
> There is a bit of a philosophical difference in how these things should
> be exposed to the user/programmer. LV has the more pure form of
> enumeration, more like the pascal language. C on the otherhand has
> defines and enums that allow just about anything. Which is correct?
> Again, it is a matter of philosophy.

Very well stated! Of course more flexibility (allow just about anything,
including the pascal form) usually wins.

> Instead, each
> time you need to call a specific function in the DLL, make a small
> wrapper subVI with the configured DLL node, and exposing the parameters
> which you want to be able to change and using constants for others.
> This is also the best place to smooth over the odd bit patterns and give
> them a strict enumeration type.

Agreed, however this will limit you to the features at design time. Let's
say I have a subVI which wraps the DLL exposing parameters to its user
(programmer).

With the current LV enumeration, the user is limited to the X
network-messages at design time. But of course the hardware designers are
working hard to add support for a new command. If instead a C style
enumeration were used; a power-user could wire in a numeric constant (the
new enumeration instead) to represent its actual bitstring quickly without
having to monkey with the huge complicated case statement which implements
mapping.

Again, the philosophical difference. It depends if you want to expose the
available commands, or the expose the actual command with a human readable
name.

I'm sure everybody has their wishlists for LV 7. I've been pretty to see the
..net integration improvements upon activeX, so I can't wait to see what LV
will have to offer. It had been such a nightmare in the past integrating
with other code requiring pointers, or requiring C style enumeration. I have
great hopes, NI always does good work!

(and I heard a rumor they're giving away LV7 for free, right?? right??)

-joey
0 Kudos
Message 6 of 6
(3,637 Views)