Precompile variable value - c#

From what I gather in C# documentation, there doesn't appear to be a way to #define variables like in C/C++. Is this correct? I just want to confirm that I'm not overlooking something. Essentially, I want to use a #define variable in /comments/ within my code:
#define _CLASS_ foo123
...
/// Here is documentation for my class _CLASS_
That's a totally fictitious use case, but hopefully that gets the point across.

C# doesn't have such a preprocessor power as in C++. Quote from MSDN:
The #define preprocessing directive: In C++ the #define directive is
commonly used to declare constant values. In C# the #define directive
cannot be used for this purpose. Constants in C# are best defined as
enumerated types (integral values only) or as static members of a
class or struct. If you have several such constants, consider creating
a separate "Constants" class to hold them.

Related

The best way to use C++ code in .NET and VBA

I wrote a native C++ library that does some math and simulations using Visual Studio 2013. I'd like to have this library easily usable from VBA and .NET (C#). Being able to easily call it from pure C would be also desired, but not necessary.
The internals of the library are quite complex and I want to expose a facade library for the clients. The API will have just a couple of functions (about 5). Each of the functions will only take 2 pointers as parameters - input and output structures.
My first idea was to create a COM DLL in C++. It seems to be easy to integrate with a COM DLL from VBA and C#. Calling COM from pure C is also possible. But I read the creating COM DLLs in C++ is painful, so I dropped that idea.
My next idea is to create a pure C DLL. I'll define the functions and all input and output nested structs in a C header file, so it's reusable both from C and C++. Here's an excerpt:
#pragma pack(push)
#define MF_MAX_PERIODS 240
#define MF_MAX_REGIONS 60
typedef enum mf_agency_model_type { FNMA, FHLMC } mf_agency_model_type;
/* BEGIN OF INPUT DATA STRUCTURES */
/* VBA structs are packed to 4 byte boundaries. */
#pragma pack(4)
typedef struct mf_boarding_loans {
int regions_count;
double timeline[MF_MAX_REGIONS];
} mf_boarding_loans;
#pragma pack(4)
typedef struct mf_agency_model_input {
mf_agency_model_type model_type;
int periods_count;
mf_boarding_loans boarding_loans;
} mf_agency_model_input;
/* BEGIN OF OUTPUT DATA STRUCTURES */
#pragma pack(4)
typedef struct mf_curves {
double dd_90_rate[MF_MAX_PERIODS];
double dd_60_rate[MF_MAX_PERIODS];
} mf_curves;
#pragma pack(4)
typedef struct mf_agency_model_output{
double wal_years;
mf_curves curves;
} mf_agency_model_output;
#pragma pack(pop)
/* BEGIN OF EXTERN FUNCTIONS */
#ifdef __cplusplus
extern "C" {
#endif
/* VBA requires _stdcall calling convention. */
MFLIB_API void _stdcall mf_run_agency_model(mf_agency_model_input *model_input, mf_agency_model_output *model_output);
#ifdef __cplusplus
}
#endif
It should be possible to call such a DLL from C/C++, VBA (via DECLARE) and C# (via PInvoke). The problem is the amount of input and output data. Ultimately, my input data structures will contain about 70 parameters (numbers and arrays of numbers), and the outputs will contain about 100 variables (also numbers and arrays of numbers). I presume that I'd have to declare the same structures both in VBA and C# again and I'd really like to avoid that. (I think I could avoid the declaration in VBA if I expose the C# code as COM to VBA. It seems to be very easy to impelement COM in C#.) My goal is to define the structures only once. Here are my questions:
1) I quickly read about C++/CLI. Could C++/CLI compile my C header to .NET MSIL so it's usable from other .NET languages without any wrappers? I think there will still be a problem with exposing the object to VBA via COM, since it requires some attributes to be added to classes/interfaces, but macros should help here.
2) Is there a tool that will generate for me the structures declarations in VBA and C# from the C code? I'm also OK with having to declare the structures in some meta language and generate C, VBA and C# structures from that.
3) Is it better to define my arrays as fixed size in C or just raw pointers? I read somewhere that it's easier for interop if the arrays have fixed size.
4) Is it better to include the child structures in the parent directly or via pointers from the interop perspective?
Is there any other way that will free me from redefining the huge data structures in multiple languages?
Thanks for your help,
Michal

Add External Dependencies to C++ DLL file

I created a DLL inside of MV C++ 2012 and when I used
Dumpbin /Exports filename
The name of the function inside of the DLL file has an equal sign inside of it. I had to use Common Language Runtime Support (/crl) because I used a DLL from C#. Is this why the name of the function would show up with an equals sign? My header file:
#ifdef ColorDLL_EXPORTS
#define ColorDLL_API __declspec(dllexport)
#else
#define ColorDLL_API __declspec(dllexport)
#endif
extern "C"{
ColorDLL_API int ColorSelect(int i);
}
ColorDLL.cpp
#include "stdafx.h"
#include "ColorDLL.h"
#using <ColorDiologeClass.dll>
extern "C"{
ColorDLL_API int ColorSelect(){
ColorDiologeClass::Class1::ColorReturn(1);
return 1;
}
}
When I used Dumpbin the name showed up as this:
Name
ColorSelect = _ColorSelect
Why is this? I am expecting it to show up as ColorSelect, not ColorSelect = _ColorSelect. And if I were to leave it this way, how would I call this function from a program like JMP where it needs the exact function name? Would it be ColorSelect? Or would it be ColorSelect = _ColorSelect?
The name is "mangled" - the return type and the parameters are enchoded into the name of the function. Should you wish to NOT have that, you would use extern "C" before the function name (or around a block of functions).
That would be name mangling, which is the under-the-covers feature of c++ that allows it to support function overloading (since it incorporates the argument types of the function into its name).
Here's another question that goes into greater detail.
Microsoft calls this "decorating" instead of mangling. They include a command line tool named "undname" that will produce the original name from the decorated name:
C:\>undname ?ColorSelect##YAHXZ
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?ColorSelect##YAHXZ"
is :- "int __cdecl ColorSelect(void)"
If you want to do the same in your own code, you can do that too, using UnDecorateSymbolName.
For what it's worth, decorating/mangling supports not only overloading, but typesafe linking. Typesafe linking stems from function overloading though it isn't really function overloading in itself.
Specifically, typesafe linking deals with (for example) how to deal with C++ code that has overloads of, say, sqrt for float, double, long double, and probably complex as well, but links to a C library that provides a double sqrt(double), but not the other overloads. In this case, we typically want that to be used when the right arguments were/are used, but not otherwise.
This can (or could) arise even without function overloading being involved. For example, in pure C you could do something like this:
#include <stdio.h>
extern int sqrt(int);
// ...
printf("%d", sqrt(100));
Now, we've told the compiler we're using a version of sqrt that takes (and returns) an int. Unfortunately, the linker doesn't realize that, so it still links with the sqrt in the standard library that takes and returns double. As a result, the code above will print some thoroughly useless result (typically 0, not that it matters a lot).
Typesafe linkage prevents that -- even though it isn't exactly function overloading, we still have two functions with the same name, but different types by the time we're linking. By encoding the parameter type(s) into the name, the linker can keep this sorted out just as well as the compiler can.
The same can (and frequently does) arise in C when we have name collisions between different libraries. With a traditional C compiler, straightening out this sort of mess can be extremely difficult (at best). With a C++ compiler, unless the two libraries use not only the same names, but identical number and types of parameters, it's never a problem at all.

What is the cost of a #define?

To define constants, what is the more common and correct way? What is the cost, in terms of compilation, linking, etc., of defining constants with #define? It is another way less expensive?
The best way to define any const is to write
const int m = 7;
const float pi = 3.1415926f;
const char x = 'F';
Using #define is a bad c++ style. It is impossible to hide #define in namespace scope.
Compare
#define pi 3.1415926
with
namespace myscope {
const float pi = 3.1415926f;
}
Second way is obviously better.
The compiler itself never sees a #define. The preprocessor expands all macros before they're passed to the compiler. One of the side effects, though, is that the values are repeated...and two identical strings are not necessarily the exact same string. If you say
#define SOME_STRING "Just an example"
it's perfectly legal for the compiler to add a copy of the string to the output file each time it sees the string. A good compiler will probably eliminate duplicate literals, but that's extra work it has to do. If you use a const instead, the compiler doesn't have to worry about that as much.
The cost is only to the preprocessor, when #defines are resolved (ignoring the additional debugging cost of dealing with a project full of #defines for constants, of course).
#define macros are processed by the pre-processor, they are not visible to the compiler. And since they are not visible to the compiler as a symbol, it is hard to debug something which involves a macro.
The preferred way of defining constants is using the const keyword along with proper type information.
const unsigned int ArraySize = 100;
Even better is
static const unsigned int ArraySize = 100;
when the constant is used only in a single file.
#define will increase Compilation time but it will faster in execution...
generally in conditional compilation #define is used...
where const is used in general computation of numbers
Choice is depends upon your requirement...
#define is string replacement. So if you make mistakes in the macros, they will show up as errors later on. Mostly incorrect types or incorrect expressions are the common ones.
For conditional compilation, pre-processor macros work best. For other constants which are to be used in computation, const works good.
CPU time isn't really the cost of using #define or macros. The "cost" as a developer is as follows:
If there is an error in your macro, the compiler will flag it where you referenced the macro, not where you defined it.
You will lose type safety and scoping for your macro.
Debugging tools will not know the value of the macro.
These things may not burn CPU cycles, but they can burn developer cycles.
For constants, declaring const variables is preferable, and for little type-independent functions, inline functions and templates are preferable.

How to define constants in Visual C# like #define in C?

In C you can define constants like this
#define NUMBER 9
so that wherever NUMBER appears in the program it is replaced with 9. But Visual C# doesn't do this. How is it done?
public const int NUMBER = 9;
You'd need to put it in a class somewhere, and the usage would be ClassName.NUMBER
static class Constants
{
public const int MIN_LENGTH = 5;
public const int MIN_WIDTH = 5;
public const int MIN_HEIGHT = 6;
}
// elsewhere
public CBox()
{
length = Constants.MIN_LENGTH;
width = Constants.MIN_WIDTH;
height = Constants.MIN_HEIGHT;
}
You can't do this in C#. Use a const int instead.
Check How to: Define Constants in C# on MSDN:
In C# the #define preprocessor
directive cannot be used to define
constants in the way that is typically
used in C and C++.
in c language: #define (e.g. #define counter 100)
in assembly language: equ (e.g. counter equ 100)
in c# language: according to msdn refrence:
You use #define to define a symbol. When you use the symbol as the expression that's passed to the #if directive, the expression will evaluate to true, as the following example shows:
# define DEBUG
The #define directive cannot be used to declare constant values as is typically done in C and C++. Constants in C# are best defined as static members of a class or struct. If you have several such constants, consider creating a separate "Constants" class to hold them.
In C#, per MSDN library, we have the "const" keyword that does the work of the "#define" keyword in other languages.
"...when the compiler encounters a constant identifier in C# source code (for example, months), it substitutes the literal value directly into the intermediate language (IL) code that it produces."
( https://msdn.microsoft.com/en-us/library/ms173119.aspx )
Initialize constants at time of declaration since there is no changing them.
public const int cMonths = 12;
What is the "Visual C#"? There is no such thing. Just C#, or .NET C# :)
Also, Python's convention for constants CONSTANT_NAME is not very common in C#. We are usually using CamelCase according to MSDN standards, e.g. public const string ExtractedMagicString = "vs2019";
Source: Defining constants in C#

Is it possible to share an enum declaration between C# and unmanaged C++?

Is there a way to share an enum definition between native (unmanaged) C++ and (managed) C#?
I have the following enum used in completely unmanaged code:
enum MyEnum { myVal1, myVal2 };
Our application sometimes uses a managed component. That C# component gets the enum item values as ints via a managed C++ interop dll (from the native dll). (The interop dll only loads if the C# component is needed.) The C# component has duplicated the enum definition:
public enum MyEnum { myVal1, myVal2 };
Is there a way to eliminate the duplication without turning the native C++ dll into a managed dll?
You can use a single .cs file and share it between both projects. #include in C++ on a .cs file should be no problem.
This would be an example .cs file:
#if !__LINE__
namespace MyNamespace
{
public
#endif
// shared enum for both C, C++ and C#
enum MyEnum { myVal1, myVal2 };
#if !__LINE__
}
#endif
If you want multiple enums in one file, you can do this (although you have to temporarily define public to be nothing for C / C++):
#if __LINE__
#define public
#else
namespace MyNamespace
{
#endif
public enum MyEnum { MyEnumValue1, MyEnumValue2 };
public enum MyEnum2 { MyEnum2Value1, MyEnum2Value2 };
public enum MyEnum3 { MyEnum3Value1, MyEnum3Value2 };
#if __LINE__
#undef public
#else
}
#endif
Thanks for sharing!
I played around a bit and found a way to have multiple enum and constant declarations without having tons of extra lines :)
// This is a valid C, C++ and C# file :)
#if __LINE__
#define public
#else
namespace MyCSharpNamespace{
#endif
public enum MyConstant { MaxStr = 256 };
public enum MyEnum1{ MyEnum1_A, MyEnum1_B };
public enum MyEnum2{ MyEnum2_A, MyEnum2_B };
#if __LINE__
#undef public
#else
}
#endif
Remember to name your file *.cs
You can expose the C# library to COM and then import the type library into the unmanaged code - this way you will be able to use the enum defined in C# library in the unmanaged library.
Unmanaged C++ and C# live in two different worlds, so no there is no way to use the same enum, without changing the c++ DLL into a managed one.
And even then, you'd probably need the duplication in the managed C++ DLL.
A C++ enum is much like a list of constants, whereas a C# enum inherits the Enum class, and thus provides quite a few "tricks". So as you can see, they're very different.
If it doesn't matter whether the native C++ DLL is native or managed, I'd turn it into a managed one and wrap the native calls inside a managed C++ Layer.
That way you can have the enum duplication inside the C++ DLL, and also you can get rid of all the interop at the same time :-)
I've had the same problem in the past and solved it using preprocessor definitions.
In your unmanaged code, inside a header that can also be included by your managed wrapper, place your enumeration items into a #define.
Then, in your managed and unmanaged enumeration definitions, use the same #define for both usages.
The movement of the enumerations between the managed and unmanaged world looks slightly nasty (basically a cast is needed), but to your caller in the unmanaged world, it'll look and feel fine.
Good luck,

Categories