Reputation: 20311
As far as I know, C++ standards does not guarantee the size of the basic data types like int
for example. It just guarantees the the minimum number of bits that represents the int
variable. So, from platform to platform this may change.
When working with application that contains both managed and native parts (C++ & C#) with normal C style interface (Pinvokes
and Marshal
..), this inconsistent of datatypes size may result in a lot of mess.
So, is it good to use always fixed size data types in the interface? does it have any drawbacks?
Upvotes: 0
Views: 187
Reputation: 15533
For integer types: Yes you should.
It's easier on the C# side since all integers types have a fixed size that does not depend on the platform bit-ness.
On the C++ side you can use the following corresponding types:
int8_t
-> sbyte
= System.SByte
, This is not ECMA standard but available in :NET and Mono
uint8_t
-> byte
= System.Byte
int16_t
-> short
= System.Int16
uint16_t
-> ushort
= System.UInt16
int32_t
-> int
= System.Int32
uint32_t
-> uint
= System.UInt32
int64_t
-> long
= System.Int64
uint64_t
-> ulong
= System.UInt64
Exchanging pointer types is also safe. Although their size can vary it is always the same on the caller and callee size for a specific process.
I.e.: if the process is 64 bit, your C++ code must have been compiled as 64 bit so it's pointers have 64 bit. This process would use the 64 bit .NET runtime so pointers in .NET would also be 64 bit.
(BTW: Pointer types in C# are System.IntPtr
and ... *
).
For floating point types it's a bit harder. The C++ standard does not give you any hint how a float
or double
is stored. Not the size nor the technique.
In reality all C/C++ compiler that I know of (MSVC, gcc/g++, clang/clang++) on all platforms I have used them (Windows, MinGW, Linux) do store float
in 32 bit IEEE-754 format and double
in 64 bit IEEE-754 format.
I don't know if .NET defines a fix format but in my experience .NET and Mono do it the same way (float
= System.Single
is 32 bit IEEE-754 and double
= System.Double
is 64 bit IEEE-754).
So you can decide if you trust my observations for the C++ side or not...
Upvotes: 2
Reputation: 1244
You can define your own datatypes which does not change in size regardless of the architecture you use. The advantage is you need not modify your program when you move to different arch(e.g. 32 to 64 bit etc). The drawback is, assume you have initially written your program for 32bit and consider the following and you have defined a 64 bit data type like this.
typedef struct A
{
int a;
int b;
} my64bitint;
To use this you need to write your own code. When you move to 64 bit, then you can continue to use the same, but then you will not get the advantage of the 64 bit integer you get in the new arch. You need to change the code to use 64 bit integer.
Upvotes: 0
Reputation: 1717
As C# int
is always 32bit, you must ensure that your C++ part uses 32bit integers too when interfacing. Drawbacks should not worry you, as this is a must.
Also, it is not clear that 64 bits integer would be good or bad for you. It depends on what you are doing. They will take more space, that's for sure.
Upvotes: 0