tags:

views:

58

answers:

2

Hello All,

We have a situation where we use a set of third-party unmanaged C++ libraries in our C# (WPF) application, but we also use a subset of their include libraries to build our own unmanaged libraries to use in our application.

These libraries produce metadata, which is stored in a database. However, we must replicate some constants related to this metadata in our C# code, in order to use the metadata.

There is a potential issue, then, if some of these constants change between versions. Is there a clean way for the C# application to use the constants defined in the C++ include files?

Thanks, wTs

+2  A: 

You'll need to redefine them inside C#, in your C# wrapper classes.

Unfortunately, if the constants change, you'll need to modify your copy as well. (Changing constant values between versions is a very bad idea, however, so hopefully the 3rd party API won't do this to you...)


That being said, there are options for this. You could, for example, make a small C++ program that uses the API, and writes all of the constants out into a .cs file with the correct format. This would protect you if the constants change between versions (at least, if the values change), but you'll still need to update your program to handle additional constants in future versions, if required.

Another option would be to use C++/CLI to expose the constants directly within a class, and reference that assembly and class from C#.

Reed Copsey
`if the constants change` - nice oxymoron.
Mark H
+1 I had to use an old C++ library inside of a C# application recently and what Reed is describing is pretty much exactly, make copies, what I had to do.
ChadNC
You mean, "hopefully the 3rd party API won't do this to you AGAIN..." :)
Wonko the Sane
@Mark: Very nice! @Wonko: I'd complain to the 3rd party, and ask them not to do this to you again. It's a very poor practice.
Reed Copsey
+1  A: 

I have a solution that you may not consider terribly "clean" but which will work. The problem is that using either an enum or #define preprocessor directives will discard the symbolic name you're using for the constant (like ERR_OUT_OF_MEMORY will really just be some integer).

In the C++ code, you could define a function which takes in a string name of the symbol and returns its value. You could use an std::map, then add pairs such as std::pair("ERR_OUT_OF_MEMORY", ERR_OUT_OF_MEMORY) Then you can call that function from the DLL using DllImportAttribute which allows unmanaged interop in .NET. Unfortunately this requires going through and string-ifying the constants, but the advantage is that if these constants change, it will be automatic.

Another solution is to write a simple script that goes through preprocessor #defines and creates a gigantic .NET class with a bunch of static constants with the same name. This actually wouldn't be that hard considering the simplicity of the preprocessor (should only take a few lines of Perl)

bowenl2
Writing a script is actually something that I am considering - I was just wondering if I was missing the boat on a generally accepted method.
Wonko the Sane