In C# we have a datatype object which can hold any type of data. Same thing I want to achieve in VC++. Can anyone kindly let me know VC++ equivalent of "Object of C#".
IN C#, in the calling appl program (say call.cs)
object ob=null;
ob=(object)str;
funct(ref ob);
Here str is empty string.
This thing I want to achieve in VC++. So I need to create VC++ equivalent of object.
I am sure we need to use pointers as ref's equivalent??
There isn't one. C++ doesn't have a unified type hierarchy like .NET languages have.
The closest you can get is a void* (pointer-to-void), which can point to any type of object. You should avoid void*s like the plague, though; once you start using them you lose any and all type safety.
As other commentators have said, C++ does not have a common base-class for every object. Theoretically, you could create your own and derive everything from it:
class Object
{
protected:
Object(){};
virtual ~Object(){};
public:
virtual std::string toString() const {return("");};
}; // eo class Object
This, however, won't help you with integral types such as int, short. You'd have to make your own:
class Int : public Object
{
private:
int m_nVal;
public:
Int(int _val = 0) : m_nVal(_val){};
Int(const Int& _rhs) : m_nVal(_rhs.m_nVal){};
virtual ~Int(){};
// operators
operator int() const {return(m_nVal);}
bool operator == (const Int& _rhs) const {return(m_nVal == _rhs.m_nVal);};
bool operator == (int _val) const {return(m_nVal == _val);};
Int& operator = (const Int& _rhs) {m_nVal = _rhs.m_nVal; return(*this);}:
Int& operator = (int _val) {m_nVal = _val; return(*this);};
// .... and all the other operators
// overrides
virtual std::string toString() const
{
std::ostringstream oss;
oss << m_nVal;
return(oss.str());
};
}; // eo class Int
You'd then have to do this for all the other types you want to use. Once done you can pass them around as if they were ints, bools, longs etc (thanks to operator overloading). A better method would be to use a template class for the integral types:
template<class T> class IntegralType : public Object
{
private:
T m_Val;
public:
// rest of class looks the same
}; // eo class IntegralType<>
Then typedef them away:
typedef IntegralType<int> Int;
typedef IntegralType<short> Short;
typedef IntegralType<long> Long;
Even using a template-class like this to take the leg-work out of it, you'd still need a specialisation for strings/bools. implementing operator ++ on IntegralType<> will work fine for numbers, but is going to throw up on std::string.
If you went the template route, you've now got "Object", integral types and some specialisations for strings, bools. But to mimick .NET even more, you probably want to introduce interfaces for comparisons:
template<class T> class IEquitable
{
public:
virtual Equals(T _other) = 0;
}; // eo class IEquitable<>
That can easily be plumbed in to your IntegralType<> classes and the specialisations.
But as another commentator pointed out, why would you? boost::any is useful if you're trying to do something like a Tuple which has a name and a value of an arbitrary type. If you need to build a collection of these then there is something fundamentally wrong with your design. For example, in all my coding in C# I have never had to write:
List<Object> list = new List<Object>();
There may have been:
List<Vehicle> list;
List<Employee> List;
Dictionary<string, Alien> aliens;
But never anything at the Object level. Why? Well apart from calling ToString() on it, or perhaps doing some risky casting, why would you want to? Generics exist in programming so that we do not have to have lists of objects (or in the case of C++, void*).
So there you have it. The above shows how you might have objects and integral types working kind of like C#, and I've missed a chunk of stuff out. Now it's time to look at your design and decide if that's what you really need to do.
There's nothing built into the language. Usually, wanting it at all indicates that your design isn't very well thought out, but if you can't figure out any alternative, you might consider (for one example) Boost any.
The <comutil.h> header contains a handy wrapper for VARIANT. Takes care of proper initialization and cleanup.
#include <comutil.h>
#ifdef _DEBUG
# pragma comment(lib, "comsuppwd.lib")
#else
# pragma comment(lib, "comsuppw.lib")
#endif
...
_variant_t arg = L"some string";
someComPtr->func(&arg);
There isn't anything in your code snippet that would help me help you figuring out how to obtain the COM interface pointer. Start a new question about that if you have trouble.
The alternative for you is to look at System.Runtime.InteropServices.GCHandle, which allows you to find the managed object from unmanaged code, but in any way you will end up with nasty and risky type casts and you need to be really careful to keep somewhere a reference to the managed object as it might get garbage-collected if there is only a reference in unmanaged code.
Related
Starting in C++11, one can write something like
#include <vector>
#include <string>
struct S
{
S(int x, const std::string& s)
: x(x)
, s(s)
{
}
int x;
std::string s;
};
// ...
std::vector<S> v;
// add new object to the vector v
// only parameters of added object's constructor are passed to the function
v.emplace_back(1, "t");
Is there any C# analogue of C++ functions like emplace or emplace_back for container classes (System.Collections.Generic.List)?
Update:
In C# similar code might be written as list.EmplaceBack(1, "t"); instead of list.Add(new S(1, "t"));. It would be nice not to remember a class name and write new ClassName in such situations every time.
In general there is nothing similar in C#, and its need is much less than in C++.
In C# when you have a List<SomeReferenceType> what you really have is a List<ReferenceToSomeType>, so a list of references, with the size of each element of 4 or 8 bytes (see How big is an object reference in .NET?). Copying a reference doesn't cause the underlying object to be duplicated, so it is very fast (you are copying around 4 or 8 bytes, and the processor is optimized for this operation, because that is the size of the native pointer of the processor). So when you someList.Add(someReference) what you are doing is adding a reference to your List<>.
In C++ when you have a std::vector<SomeType> what you have is a vector of SomeType, with the size of each element equal to sizeof(SomeType). Inserting a new element in std::vector<> will cause the element you are inserting to be duplicated (cloned, copied... choose a verb you like). This is an expensive operation.
Quite often the pattern you use is that you create an object just to insert it into a std::vector<>. To optimize this operation in C++11 they added two ways to do it: the std::vector<>::emplace method and support by the std::vector<> of the move semantic. The difference is that the move semantic must be supported by the SomeType type (you need a move constructor with the noexcept specifier), while every type supports the emplace (that in the end simply used placement constructor).
You can a bit improve #Boo variant with extenstion.
You can create object instance with Activator.CreateInstance so it make solution more generic.
public static class ListExtension
{
public static void Emplace<S>(this IList<S> list, params object[] parameters)
{
list.Add((S)Activator.CreateInstance(typeof(S), parameters));
}
}
Note: not checked type and count parameters, so if you do something wrong, you get errors just in run-time
in c# you can use extension method to achive what you want
public static class ListExtension
{
public static void Emplace(this IList<S> list, int x, string s)
{
list.Add(new S(x, s));
}
}
then use it like this
myList.Emplace(1,"t");
It seems you have following problems:
It's longer to type by "new S". But "add" is shorter than "emplace". Type is added for you by intellisense (simply press Enter after typing "new "):
You are afraid to write a wrong type. Well you can't with List<T>. Intellisense will help you to type and compiler will not allow wrong type to be added at compile time anyway.
Performance: see #Xanatos answer.
list.Add(new S(1, "t")); is perfectly fine to use.
Conclusion: we don't need emplace in C#.
I have arrived at a point in my self-taught studies where I am not fully grasping what a delegate in C# is useful for. Additionally, on a whim, I decided to take a look at an intro to C++ site and I came across function templates.
Maybe I'm comparing apples and oranges here, but I understood a delegate to be a sort of template for a function that would be defined at run-time. Is this true? If so, how does that differ from a function template in C++?
Is it possible to see (realistic) examples of each in use?
A delegate is a way of taking a member function of some object, and creating a...thing that can be called independently.
In other words, if you have some object A, with some member function F, that you'd normally call as something like: A.F(1);, a delegate is a single entity that you can (for example) pass as a parameter, that acts as a proxy for that object/member function, so when the delegate is invoked, it's equivalent to invoking that member function of that object.
It's a way of taking existing code, and...packaging it to make it easier to use in a fairly specific way (though I feel obliged to add, that 'way' is quite versatile so delegates can be extremely useful).
A C++ function template is a way of generating functions. It specifies some set of actions to take, but does not specify the specific type of object on which those actions will happen. The specification is at a syntactic level, so (for example) I can specify adding two things together to get a third item that's their sum. If I apply that to numbers, it sums like you'd expect. If I do the same with strings, it'll typically concatenate the strings. This is because (syntactically) the template just specifies something like a+b, but + is defined to do addition of numbers, and concatenation of strings.
Looked at slightly differently, a function template just specifies the skeleton for some code. The rest of that code's body is "filled in" based on the type, when you instantiate the template over some specific type.
In C++ terms a C# delegate combines an object pointer and a member function pointer into one callable entity, which calls the member function on the pointed to object.
You can do about the same with std::bind and std::function.
Before C++11 there was a short flurry of articles on how to do very efficient delegates in C++. std::function is a very reasonable compromise and may even attain those levels of efficiency.
Example:
#include <iostream>
#include <functional>
using namespace std;
// Here `function<void()>` serves as a "delegate" type.
void callback_on( function<void()> const f )
{
f();
}
struct S
{
int x;
void foo() const { cout << x << endl; }
};
int main()
{
S o = {42};
callback_on( bind( &S::foo, &o ) );
}
I am writing a C wrapper an would like to use a typedef aquivalent to define some types which should be valid in quite a lot of source files. Those "types" are just different aliases to [u]int16/32/64_t, but are useful to distinguish function parameters.
One could use using MyId=System.Int32;, but this needs to be redeclared in every file as far as I see... Is there a better way?
One alternate approach is to use a struct with implicit conversion to the underlying type.
public struct MyHandle
{
private int _handle;
internal MyHandle(int handle)
{
_handle = handle;
}
public static implicit operator int(MyHandle handle)
{
return handle._handle;
}
}
Your internal code can still use it as the underlying type (int in this case) via the implicit conversion, but you expose it as a strong type to the user. Your user can also see the int value, though it's effectively meaningless to them. They can't directly cast an int to your Handle type, as the constructor is internal to your assembly and you don't provide a conversion operator for the other direction.
Since I'm assuming that you want to distinguish between a legitimate use of say UInt32 and your custom type, yes you would need to manually reference your alias everywhere you want it to be used.
Please, help me with this problem:
I Try define a structure like this:
unsafe struct sNodo<T>
{
public T info;
public sNodo<T>* sIzq;}
but i get this error: Cannot take the address of, get the size of, or declare a pointer to a managed type sNodo,
how can I fix it?
I'm trying to create a stack "generic" using dynamic memory.
Thank you for your attention
If all you need is to create a generic stack, you don't need unsafe. Just use the normal C# language:
class StackNode<T> {
public T info;
public StackNode<T> next;
}
Why exactly do you feel you need unsafe?
Maybe you're thinking that you need a pointer because the otherwise your type can't have another instance of the same type as a data member. Indeed, in C# if you try to do:
struct Foo {
int data;
Foo next;
}
...the C# compiler will complain about circular struct references and refuse to compile your code (if you don't see why it has to do that, try to figure out how many bytes a Foo object should take up in memory).
But if you try to do the same thing with the class keyword:
class Bar {
int data;
Bar next;
}
...everything works! If you come from a C++ background, where classes and structs are more or less the same thing, this is very puzzling.
The secret is that in C#, structs have value semantics while classes have reference semantics. So the C++, the above two definitions are most similar to:
class Foo {
int data;
Foo next; // This doesn't compile in C++ either.
}
class Bar {
int data;
Bar* next; // But this is ok.
}
This C++ code isn't completely equivalent, of course, but it should give you a basic idea of what to expect.
Bottom line: if you're just learning C#, don't use structs; everything they can do, classes can do too. Once you understand C# semantics, and are sure that the value semantics structs give you can provide you with a performance benefit, and are sure that that performance benefit actually matters to your app, go ahead and use them.
Here is a C# program that tries Marshal.SizeOf on a few different types:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
class AClass { }
[StructLayout(LayoutKind.Sequential)]
struct AStruct { }
[StructLayout(LayoutKind.Sequential)]
class B { AClass value; }
[StructLayout(LayoutKind.Sequential)]
class C<T> { T value; }
class Program
{
static void M(object o) { Console.WriteLine(Marshal.SizeOf(o)); }
static void Main()
{
M(new AClass());
M(new AStruct());
M(new B());
M(new C<AStruct>());
M(new C<AClass>());
}
}
The first four calls to M() succeed, but on the last one, SizeOf throws an ArgumentException:
"Type 'C`1[AClass]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
Why? Specifically, why does SizeOf choke on C<AClass>, but not on B or on C<AStruct>?
EDIT: Because it was asked about in the comments, here's the "real-world" problem that inspired this mostly-academic question:
I'm calling into a C API that is basically one C function that operates on (pointers to) lots of different types of simple C structures. All contain a common header followed by one field, but the type of that field is different in different structures. A flag in the header indicates the type of the field. (Strange, yes, but that's what I have to work with).
If I could define a single generic type C<T> and a single C# extern declaration M(C<T>), and then call M(C<int>) on one line, and M(C<double>) on another, I'd have a short and sweet interop solution. But given JaredPar's answer, it appears that I have to make a separate C# type for each structure (though inheritance can provide the common header).
Generics as a rule are not supported in any interop scenario. Both P/Invoke and COM Interop will fail if you attempt to marshal a generic type or value. Hence I would expect Marshal.SizeOf to be untested or unsupported for this scenario as it is a marshal-specific function.
It is not known what size the aggregated object T would have (it would be the size of a pointer if T is a referenece type and mostly any value if it is value type).
I think you can solve this problem by setting the MarshalAs attribute on the field 'value' specifying the most matching type (for example, Unmanagedtype.SysInt). Note that it still won't work for so-called non-mappable types (i.e. types for which fields offsets and sizes can't be deduced easily).
But AFAIK, it's not recommended to use generics in interop.