What is equivalent of the VARIANT datatype of C++ in C#?
I have code in C++ which uses the VARIANT datatype. How can I convert that code in C#?
Well, there are actually two variant's in C++: boost::variant and COM variant. The solution follows more or less the same idea, but the former is more complex. I expect you mean to use the latter.
Let me first start by telling that this is something you just shouldn't use if possible. That said, this is how you do it :-)
Variants and interop
Variants are sometimes used in interop of if you need the byte representation to be the same.
If you're dealing with interop, make sure to check out the VariantWrapper class on MSDN and make it work like that.
Variants and porting considerations
Variants are mostly used in APIs, and usually like this:
void Foo(SomeEnum operation, Variant data);
The reason it's done like this in C++ is because there is no base object class and you therefore need something like this. The easiest way to port this is to change the signature to:
void Foo(SomeEnum operation, object data);
However, if you're porting anyway, you also seriously want to consider these two, since they are resolved at compile-time and can save you the big 'switch' that usually follows in method Foo:
void SomeOperation(int data);
void SomeOperation(float data);
// etc
Variants and byte consistency
In rare cases you need to manipulate the bytes themselves.
Essentially the variant is just a big union of value types wrapped in a single value type (struct). In C++, you can allocate a value type on the heap because a struct is the same as a class (well sort-of). How the value type is being used is just a bit important but more on that later.
Union simply means you are going to overlap all the data in memory. Notice how I explicitly noted value type above; for variant's this is basically what it's all about. This also gives us a way to test it - namely by checking another value in the struct.
The way to do this in C# is to use the StructLayout attribute in a value type, which basically works as follows:
[StructLayout(LayoutKind.Explicit)]
public struct Variant
{
[FieldOffset(0)]
public int Integer;
[FieldOffset(0)]
public float Float;
[FieldOffset(0)]
public double Double;
[FieldOffset(0)]
public byte Byte;
// etc
}
// Check if it works - shouldn't print 0.
public class VariantTest
{
static void Main(string[] args)
{
Variant v = new Variant() { Integer = 2 };
Console.WriteLine("{0}", v.Float);
Console.ReadLine();
}
}
C++ variant's can also be stored on the heap as I noted earlier. If you do this, you probably still want the memory signature to be the same. The way to do this is to box the Variant struct we build earlier by simply casing it to object.
This is a tricky question.
From C# 4, you can use dynamic to indicate that the type is known at run-time.
By my personal understanding, however, c++ requires the type known at compile time. Thus you might consider to use object, but object in C# is an existent type.
For the concept of multi-type, single value (AKA polymorphism) of VARIANT, you would not need to find a corresponding type in C#, just define your classes and interfaces. You can always reference an object as its interface which the class implements.
If you are porting the code, and to figure out a syntax that you can simply use in LHS and for the considering of the type is known at compile time, then use var.
When .NET implements a COM interface, just use VARIANT* instead.
Then bypass marshalling on the .NET receiving side by using a IntPtr type to receive the pointer.
public class ComVariant
{
[StructLayout(LayoutKind.Sequential)]
public struct Variant
{
public ushort vt;
public ushort wReserved1;
public ushort wReserved2;
public ushort wReserved3;
public Int32 data01;
public Int32 data02;
}
private Variant _variant;
private IntPtr _variantPtr;
public ComVariant(int variantPtr) : this(new IntPtr(variantPtr))
{
}
public ComVariant(IntPtr variantPtr)
{
_variant = (Variant)Marshal.PtrToStructure(variantPtr, typeof(Variant));
_variantPtr = variantPtr;
}
public VarEnum Vt
{
get
{
return (VarEnum)_variant.vt;
}
set
{
_variant.vt = (ushort)value;
}
}
public object Object
{
get
{
return Marshal.GetObjectForNativeVariant(_variantPtr);
}
}
}
then if you are accessing a VT_UNKNOWN pointing to a COM interface object instance, just
var variant = new ComVariant(variantPtr);
var stream = variant.Object as IStream; // will not be null if type is correct
var obj = variant.Object as IObj; // in general...
will do the trick, but pay attention not to use a newly allocated VARIANT and giving its ownership to the .NET implementation without deallocating it somewhere...
For more complex code you might read this article which also talks about memory management.
Let's take a step back. Sooner or later, we want the actual data in the VARIANT. A VARIANT is just a holder for meaningful data. Suppose we converted the VARIANT to some sort of Object in C# that had the variant type and some raw buffer under the .NET hood (e.g. .NET strings can expose the raw buffer). At that point, the VARIANT type would need to be determined from the object and the raw data converted or cast to the data type specified by the variant, and then create a new Object e.g. string/int/etc. from the raw data.
So, rather than worry about passing the VARIANT to C#, look at the variant data type and convert it in C++ to the actual data type and pass that to C#.
For example, if the VARIANT type is VT_INT, then get the int from the variant and can use something like:
VARIANT var;
Int^ returnInt = gcnew Int(var.intVal);
returnInt can be returned as an Out parameter from a C++ function in a C++ dll that can be called from C#. The C++ dll needs to use /clr option.
Function would look like:-
void ThisFunctionReturnsAnInt(Runtime::InteropServices::OutAttribute Int^ % returnIntValue)
{
VARIANT var;
Int^ returnInt = gcnew Int(var.intVal);
}
Can use similar approach for other data types. It's only natural, a VARIANT of VT_INT is really just like an int, it's not as if there's some major conversion going on, you're just taking the actual value out of the VARIANT at the time when you're interested in it as you would if you were passing a straight integer value from C++ to C#. You would still need to do the gcnew anyway.
Related
I'm trying to get a C# class (not struct!) from a C++ function back (using out parameter). This is the C# side:
[StructLayout(LayoutKind.Sequential)]
public class OutClass
{
public int X;
}
// This interface function will be mapped to the C++ function
void MarshalOutClass(out OutClass outClass);
The C++ part looks like this
struct OutClass
{
int x = 0;
};
extern "C" MARSHAL_TESTS_API void MarshalOutClass(OutClass** out);
The function mapping works via a custom mechanism and is not part of this question. All marshaling attributes are treated normally.
In C#, we usually declare out arguments inline, like:
MarshalOutClass(out var outClass);
DoSomething(outClass);
Since C# reference types are marshaled by pointer, I figured I would have to add another pointer for ref or out parameters. So I use OutClass** on the C++ side.
I assume that C# translates the
MarshalOutClass(out var outClass);
part to roughly
OutClass outClass = default(OutClass);
MarshalOutClass(ref outClass);
which is a reference to null, or on C++ side: a pointer to a nullptr. This wouldn't be a problem for C# value types (aka struct) because their default is a default constructed instance.
This means, I'd have to manually create an instance of my object on the C++ side and marshal it back to C#.
void MarshalOutClass(OutClass** out)
{
auto ptr = static_cast<OutClass*>(CoTaskMemAlloc(sizeof(OutClass)));
*ptr = OutClass{};
*out = ptr;
}
The code seems to work, but I'm not sure if I'm leaking memory with this or if the marshaler is going to to take care of it properly. I don't do any cleanup on the C# side.
This brings me to the following questions:
is my assumption on how ref and out are translated to C++ correct?
is CoTaskMemAlloc the correct function here?
do I have to perform any additional memory management related tasks (on either side)?
is the overall approach correct here? What should I do differently?
I know that static_cast<OutClass*>(CoTaskMemAlloc(sizeof(OutClass))) is a bit sketchy here but lets assume OutClass is always a trivial type.
I have to wrap the following c++ function:
class Foo {
unsigned int *getVector3();
};
The member function getVector3, returns a (fixed) 3D array, eg [1,2,3]. How should I use arrays_csharp.i for a return type ? The documentation only describes for input parameters:
22.4 C# Arrays
In my case the return type is always a fixed size array (of 3 elements).
I have an answer, although it's not entirely satisfactory in my view. That's mostly limited by my knowledge of C# though, so you can probably make it work better than I can.
I don't think arrays_csharp is what you're looking for here. It seems to be about pinning memory so it can be used as input to a function, but in your scenario you've got memory already allocated that you'd like to work with.
That's fairly easy (and for a 3D vector pretty cheap), using System.InteropServices.Marshal normally. So I put together a few typemaps using that which does what you want:
%module test
%typemap(csout,excode=SWIGEXCODE) unsigned *getVector {
global::System.IntPtr cPtr = $imcall;$excode
int[] tmp = new int[3];
// I have no idea why Marshal.Copy does not seem to have any support for unsigned types...
global::System.Runtime.InteropServices.Marshal.Copy(cPtr, tmp, 0, 3);
// There is probably a better way to go from int[3] -> uint[3], but it is not obvious to me
return new $typemap(cstype, $*1_type)[3]{($typemap(cstype, $*1_type))tmp[0],($typemap(cstype, $*1_type))tmp[1],($typemap(cstype, $*1_type))tmp[2]};
}
%typemap(cstype) unsigned *getVector "$typemap(cstype, $*1_type)[]"
%inline %{
unsigned *getVector() {
static unsigned arr[3] = {1,2,3};
return arr;
}
%}
A few notes though:
$typemap(cstype, $*1_type) is a fancy way of saying find me the C# type corresponding to my C element type. I tend to try and avoid explicitly writing types in typemaps as it makes things more generic.
Having said that Marshal.Copy only seems to work with signed rather than unsigned array types, for reasons I can't quite figure out. And I can't see an automatic way to find the corresponding signed type for an unsigned one, so I did have to explicitly write int[]
I'm not sure that signed -> unsigned casting is actually well defined behaviour in C#. Maybe this won't work properly for values where the last bit is set. You can work around that by increasing the size of the int type for tmp. (E.g. use int64 instead of int32, but that's not pretty)
There ought to be a better way to cast a whole array than what I've done, but I don't know the C# language all that well.
That said this is sufficient that I can run the following program (with Mono) and get the output expected
public class runme {
static void Main(string[] args) {
uint[] arr = test.getVector();
System.Console.WriteLine(arr[0]);
System.Console.WriteLine(arr[1]);
System.Console.WriteLine(arr[2]);
}
}
We could do a bunch more work to make this generic (i.e. other size vectors, other datatypes int16[4], etc.) if that was useful.
I have a class, and I want to inspect its fields and report eventually how many bytes each field takes. I assume all fields are of type Int32, byte, etc.
How can I find out easily how many bytes does the field take?
I need something like:
Int32 a;
// int a_size = a.GetSizeInBytes;
// a_size should be 4
You can't, basically. It will depend on padding, which may well be based on the CLR version you're using and the processor etc. It's easier to work out the total size of an object, assuming it has no references to other objects: create a big array, use GC.GetTotalMemory for a base point, fill the array with references to new instances of your type, and then call GetTotalMemory again. Take one value away from the other, and divide by the number of instances. You should probably create a single instance beforehand to make sure that no new JITted code contributes to the number. Yes, it's as hacky as it sounds - but I've used it to good effect before now.
Just yesterday I was thinking it would be a good idea to write a little helper class for this. Let me know if you'd be interested.
EDIT: There are two other suggestions, and I'd like to address them both.
Firstly, the sizeof operator: this only shows how much space the type takes up in the abstract, with no padding applied round it. (It includes padding within a structure, but not padding applied to a variable of that type within another type.)
Next, Marshal.SizeOf: this only shows the unmanaged size after marshalling, not the actual size in memory. As the documentation explicitly states:
The size returned is the actually the
size of the unmanaged type. The
unmanaged and managed sizes of an
object can differ. For character
types, the size is affected by the
CharSet value applied to that class.
And again, padding can make a difference.
Just to clarify what I mean about padding being relevant, consider these two classes:
class FourBytes { byte a, b, c, d; }
class FiveBytes { byte a, b, c, d, e; }
On my x86 box, an instance of FourBytes takes 12 bytes (including overhead). An instance of FiveBytes takes 16 bytes. The only difference is the "e" variable - so does that take 4 bytes? Well, sort of... and sort of not. Fairly obviously, you could remove any single variable from FiveBytes to get the size back down to 12 bytes, but that doesn't mean that each of the variables takes up 4 bytes (think about removing all of them!). The cost of a single variable just isn't a concept which makes a lot of sense here.
Depending on the needs of the questionee, Marshal.SizeOf might or might not give you what you want. (Edited after Jon Skeet posted his answer).
using System;
using System.Runtime.InteropServices;
public class MyClass
{
public static void Main()
{
Int32 a = 10;
Console.WriteLine(Marshal.SizeOf(a));
Console.ReadLine();
}
}
Note that, as jkersch says, sizeof can be used, but unfortunately only with value types. If you need the size of a class, Marshal.SizeOf is the way to go.
Jon Skeet has laid out why neither sizeof nor Marshal.SizeOf is perfect. I guess the questionee needs to decide wether either is acceptable to his problem.
From Jon Skeets recipe in his answer I tried to make the helper class he was refering to. Suggestions for improvements are welcome.
public class MeasureSize<T>
{
private readonly Func<T> _generator;
private const int NumberOfInstances = 10000;
private readonly T[] _memArray;
public MeasureSize(Func<T> generator)
{
_generator = generator;
_memArray = new T[NumberOfInstances];
}
public long GetByteSize()
{
//Make one to make sure it is jitted
_generator();
long oldSize = GC.GetTotalMemory(false);
for(int i=0; i < NumberOfInstances; i++)
{
_memArray[i] = _generator();
}
long newSize = GC.GetTotalMemory(false);
return (newSize - oldSize) / NumberOfInstances;
}
}
Usage:
Should be created with a Func that generates new Instances of T. Make sure the same instance is not returned everytime. E.g. This would be fine:
public long SizeOfSomeObject()
{
var measure = new MeasureSize<SomeObject>(() => new SomeObject());
return measure.GetByteSize();
}
It can be done indirectly, without considering the alignment.
The number of bytes that reference type instance is equal service fields size + type fields size.
Service fields(in 32x takes 4 bytes each, 64x 8 bytes):
Sysblockindex
Pointer to methods table
+Optional(only for arrays) array size
So, for class without any fileds, his instance takes 8 bytes on 32x machine. If it is class with one field, reference on the same class instance, so, this class takes(64x):
Sysblockindex + pMthdTable + reference on class = 8 + 8 + 8 = 24 bytes
If it is value type, it does not have any instance fields, therefore in takes only his fileds size. For example if we have struct with one int field, then on 32x machine it takes only 4 bytes memory.
I had to boil this down all the way to IL level, but I finally got this functionality into C# with a very tiny library.
You can get it (BSD licensed) at bitbucket
Example code:
using Earlz.BareMetal;
...
Console.WriteLine(BareMetal.SizeOf<int>()); //returns 4 everywhere I've tested
Console.WriteLine(BareMetal.SizeOf<string>()); //returns 8 on 64-bit platforms and 4 on 32-bit
Console.WriteLine(BareMetal.SizeOf<Foo>()); //returns 16 in some places, 24 in others. Varies by platform and framework version
...
struct Foo
{
int a, b;
byte c;
object foo;
}
Basically, what I did was write a quick class-method wrapper around the sizeof IL instruction. This instruction will get the raw amount of memory a reference to an object will use. For instance, if you had an array of T, then the sizeof instruction would tell you how many bytes apart each array element is.
This is extremely different from C#'s sizeof operator. For one, C# only allows pure value types because it's not really possible to get the size of anything else in a static manner. In contrast, the sizeof instruction works at a runtime level. So, however much memory a reference to a type would use during this particular instance would be returned.
You can see some more info and a bit more in-depth sample code at my blog
if you have the type, use the sizeof operator. it will return the type`s size in byte.
e.g.
Console.WriteLine(sizeof(int));
will output:
4
You can use method overloading as a trick to determine the field size:
public static int FieldSize(int Field) { return sizeof(int); }
public static int FieldSize(bool Field) { return sizeof(bool); }
public static int FieldSize(SomeStructType Field) { return sizeof(SomeStructType); }
Simplest way is: int size = *((int*)type.TypeHandle.Value + 1)
I know this is implementation detail but GC relies on it and it needs to be as close to start of the methodtable for efficiency plus taking into consideration how GC code complex is nobody will dare to change it in future. In fact it works for every minor/major versions of .net framework+.net core. (Currently unable to test for 1.0)
If you want more reliable way, emit a struct in a dynamic assembly with [StructLayout(LayoutKind.Auto)] with exact same fields in same order, take its size with sizeof IL instruction. You may want to emit a static method within struct which simply returns this value. Then add 2*IntPtr.Size for object header. This should give you exact value.
But if your class derives from another class, you need to find each size of base class seperatly and add them + 2*Inptr.Size again for header. You can do this by getting fields with BindingFlags.DeclaredOnly flag.
System.Runtime.CompilerServices.Unsafe
Use System.Runtime.CompilerServices.Unsafe.SizeOf<T>() where T: unmanaged
(when not running in .NET Core you need to install that NuGet package)
Documentation states:
Returns the size of an object of the given type parameter.
It seems to use the sizeof IL-instruction just as Earlz solution does as well. (source)
The unmanaged constraint is new in C# 7.3
I know in VB you can define a UDT like:
Public Type Buffer1
ProductCode As String
SerialNumber As String
Date As Date
End Type
Is it possible to create a User Defined Type in C#? I know that they are used to implement data structures. I have researched and cannot seem to find anything.
The .NET equivalent of the VB6 Type is a struct with public fields. If what you need is the equivalent of the VB6 type, you should the ignore people who are telling you not to use a mutable struct.
Some people believe all data types should behave like class objects, and since structs with exposed fields behave in ways that class objects cannot they are evil.
In reality, there are times when the equivalent of a VB6 Type can be very useful, and any attempt to achieve such functionality with anything other than an exposed-field or otherwise "mutable" struct will be more cumbersome and yield less performant code than would using a type whose natural semantics precisely match what one is trying to achieve. Note that struct fields should generally be exposed as fields rather than properties, since the whole purpose of a VB6 Type is to serve as an aggregation of data types, rather than an ecapsulation of protected state.
There is, alas, one problem with .NET structure types, which is that unless you declare a structure as an unsafe type, only usable within unsafe code (and not usable in contexts which require being able to run in a Partial Trust environment), arrays within structures cannot achieve the semantics of arrays nor fixed-length strings in a VB6 Type. C# will allow one to declare fixed-sized arrays within a struct using the fixed keyword, but as noted only in conjunction with unsafe. Any other array declarations within a struct will cause a struct to hold an array reference rather than an array. Thus:
struct MyStruct {int n; int[] Arr; }
MyStruct a,b;
a.Arr = new int[4];
a.Arr[0] = 3;
a.n = 1;
b=a; // Copies the value of n, and the array reference in Arr, but not the array contents
b.n = 2;
b.Arr[1] = 2;
After the above code runs, b has its own copy of variable n, so the write to b.n will not affect a.n. Field b.Arr, however, holds a reference to the same array as a.Arr. An assignment directly to field Arr of b could make it point to a different array from a.Arr, but the assignment to b.Arr[1] doesn't actually write to field Arr but instead writes to the array object identified by that field, which is the same object identified by field a.Arr.
In some cases, you can replace what in VB6 would be a fixed-sized array with a simple list of discrete variables. Icky, but workable. Alternatively, if the restrictions associated with fixed arrays aren't a problem, you could use those. Beyond that, there isn't any good way to include arrays within a structure.
C# have classes and structs:
public class Buffer1
{
string ProductCode;
string SerialNumber;
DateTime Date;
}
But if you don't know classes, you must previously read some articles or books about C# (e.g. CLR via C#)
A "User Defined Data Type" from Visual Basic is called a Structure in VB.Net, and a struct in C#.
public struct Buffer1
{
public string ProductCode;
public string SerialNumber;
public DateTime Date;
}
Note that unlike the VB6 Type, which always makes all fields public, fields in all .NET types, including structures, default to private.
Consider the following stucture in c++, I need to wrap this using CLI to make it usable for C#
typedef struct A
{
int b[5];
A* next;
};
How can I do so? Please help.
non-op edit:
What I've tried is the following:
public ref struct ANET
{
array<int>^ b;
ANET^ next;
ANET()
{ b = gcnew array<int>(5) }
};
now let's say we have an pointer of object of A is a, pointer of object ofANET is aNET
nSize = sizeof(a->b)/sizeof(a->b[0]);
Marshal::Copy( IntPtr( ( void * ) a->b ), aNET->b, 0, nSize);
so far I am able get the values of a->b in aNET->b but I am stuck with marshaling the pointer of a->next to aNET->next.
Thanks
That's a linked list. So one option is to write C++/CLI code to adapt the native linked list to a .net LinkedList<T>. Going down this route will mean that you need to make copies of the list whenever it is modified in the native code and needs to be returned to the managed code. And vice versa.
If making copies is not an option then you should wrap the native linked list in a managed class. So you don't try to convert the struct definition at all. Instead you write a C++/CLI managed class that encapsulates the functionality that you need to expose. I can't say much more than that because you haven't given any information on the operations that you need to perform on this list. Now have you explained what the data flow is.