Proper way to declare an enum in Managed C++ 2005? - enums

If I use /clr:oldSyntax the following should work:
public __value enum IceCreamFlavors
{
Vanilla,
Chocolate,
Sardine,
};
what is the equivalent in non-oldSyntax? How do I declare a "managed" enum in Managed C++ for .NET 2.0?
Edit:
when I follow JaredPar's advice, then if I try to pass an IceCreamFlavor to a function with the signature:
OrderFlavor(IceCreamFlavors flav)
by running
OrderFlavor(IceCreamFlavors::Sardine)
I get the error:
'IceCreamFlavors Sardine' : member function redeclaration not allowed

Try
enum class IceCreamFlavors {
Vanilla,
Chocolate,
Sardine,
};

Are you, by any chance, trying to declare your enum inside another class?
ie:
public ref class Icecream
{
public enum class flavours
{
Mint,
Vanilla,
Guac
};
};
If you are, I would guess that you need to move it out so that it is its own class instead of a nested one. (Does managed c++ allow nested classes?) My impression is that you used to be able to do it unmanaged style inside another class, but since its its own class now, you probably shouldn't be nesting them. I might be wrong. My knowledge of managed c++ and c# is kind of weak.

Related

safely passing a callback from managed code to native code

I have a lot of native classes that accept some form of callbacks, usually a boost::signals2::slot-object.
But for simplicity, lets assume the class:
class Test
{
// set a callback that will be invoked at an unspecified time
// will be removed when Test class dies
void SetCallback(std::function<void(bool)> callback);
}
Now I have a managed class that wraps this native class, and I would like to pass a callback method to the native class.
public ref class TestWrapper
{
public:
TestWrapper()
: _native(new Test())
{
}
~TestWrapper()
{
delete _native;
}
private:
void CallbackMethod(bool value);
Test* _native;
};
now usually what I would do is the following:
Declare a method in the managed wrapper that is the callback I want.
Create a managed delegate object to this method.
Use GetFunctionPointerForDelegate to obtain a pointer to a function
Cast the pointer to the correct signature
Pass the pointer to the native class as callback.
I also keep the delegate alive since I fear it will be garbage collected and I will have a dangling function pointer (is this assumption correct?)
this looks kind of like this:
_managedDelegateMember = gcnew ManagedEventHandler(this, &TestWrapper::Callback);
System::IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(_managedDelegateMember);
UnmanagedEventHandlerFunctionPointer functionPointer = static_cast<UnmanagedEventHandlerFunctionPointer >(stubPointer.ToPointer());
_native->SetCallback(functionPointer);
I Would like to reduce the amount of code and not have to perform any casts nor declare any delegate types. I want to use a lambda expression with no delegate.
This is my new approach:
static void SetCallbackInternal(TestWrapper^ self)
{
gcroot<TestWrapper^> instance(self);
self->_native->SetCallback([instance](bool value)
{
// access managed class from within native code
instance->Value = value;
}
);
}
Declare a static method that accepts this in order to be able to use C++11 lambda.
Use gcroot to capture the managed class in the lambda and extend its lifetime for as long as the lambda is alive.
No casts, no additional delegate type nor members, minimal extra allocation.
Question:
Is this approach safe? I'm fearing I'm missing something and that this can cause a memory leak / undefined behavior in some unanticipated scenario.
EDIT:
this approach leads to a MethodAccessException when the lambda calls a private method of its managed wrapper class. seems like this method must at least be internal.
I think that you should not be using gcroot but a shared pointer. Shared pointer are made to keep an object alive as long as someone is using it.
You should also use a more c++ style in your whole code by replacing raw pointer with smart pointer and template instead of std::function (a lambda can be stored in a compile time type).
For example using the code you posted :
class Test
{
// set a callback that will be invoked at an unspecified time
// will be removed when Test class dies
template <class T>
void SetCallback(T callback); // Replaced std::function<void(bool)> with T
}
public ref class TestWrapper
{
public:
TestWrapper()
: _native()
{}
private:
void CallbackMethod(bool value);
std::unique_ptr<Test> _native; // Replaced Test* with std::unique_ptr<Test>
};
After replacing the old method with this new method all over my code base, I can report that it is safe, more succinct, and as far as I can tell, no memory leaks occur.
Hence I highly recommend this method for passing managed callbacks to native code.
The only caveats I found were the following:
Using lambda expressions forces the use of a static method as a helper for the callback registration. This is kinda hacky. It is unclear to me why the C++-CLI compiler does no permit lambda expressions within standard methods.
The method invoked by the lambda must be marked internal so to not throw MethodAccessException upon invocation. This is sort of make sense as it is not called within the class scope itself. but still, delegates / lambdas with C# don't have that limitation.

C++/CLI: Wrapping method for enums

I have a enum, SDKEnum which I need to convert into a AppEnum. I need to convert it, since my project shall be a wrapper around a .NET SDK and I cannot publish internal enums of that SDK. So I need to write my "own".
Now, for every enum I have I need a method that does the following:
AppEnum GetAppEnum (SDKEnum type)
{
switch (type)
{
// Return the correct constant, since AppEnum and SDKEnum have equal constants
}
}
That way I put a SDK enum into that method and get the corresponding App enum back.
I dont want to write that method for each enum I have.. . Is there a more generic or better way of doing this?
I'm pretty new to C++/CLI / C++ coming from C#.
Thanks a lot!
I don't know how these enums are defined, but most likely they are either (old) C-style enums or (since C++11) strongly-typed enum classes.
The following code compiles, thus static_cast is your friend here:
namespace
{
enum OLD_ENUM1 { A=1,B=2};
enum OLD_ENUM2 { C=1,D=2};
enum class NEW_ENUM1 { A=1,B=2};
enum class NEW_ENUM2 { A=1,B=2};
}
int main()
{
OLD_ENUM1 o1(A);
OLD_ENUM2 o2(static_cast<OLD_ENUM2>(o1));
NEW_ENUM1 n1(NEW_ENUM1::A);
NEW_ENUM2 n2(static_cast<NEW_ENUM2>(n1));
return EXIT_SUCCESS;
}
Note that for OLD_ENUM1 and OLD_ENUM2, I cannot use the same names for the enumeration values, since they are addressed without namespace. For the strongly-typed enums, I can do that because since they are classes, they have their own namespaces.
Alright, so what did the trick was the following regular cast:
enum SDKEnum
{
One, // (2)
Two, // (1)
Three // (0)
}
enum AppEnum
{
One,
Two,
Three
}
AppEnum MethoThatNeededTheConversion(SDKEnum sdkenum)
{
// DoStuff
return static_cast<AppEnum>(sdkenum); // Wrong int values returned
}
Important to note for me was:
The SDKEnum had other integer values for the constants then my AppEnum. So I created a test application and gave out those integer values so I can sync both enums and use regular cast.
Thanks for the help #all

typedef struct syntax for C++ Windows Forms?

i'm having trouble with syntax regarding c++ Windows Forms..
this is how you obviously do it in a regular cpp project: http://www.cplusplus.com/doc/tutorial/structures/
but its not the same in windows forms :/
any help??
THANKS!
btw, i figured it out!
you must create a new class in the project...
call it, Player.h
in the new class, you must instantiate the class like below
to make it a managed class so it fits well with the managed code
in the forms (notice ref class keyword)
struct markedPos
{
int xPos;
int yPos;
};
ref class Player
{
public:
Player()
{
}
protected:
private:
};
then simply in the forms.h file, you must include the new class like any other class:
#include "Player.h"
and all you have to do is make an instance of the player in your forms and it'll work like magic! What i've learned: Do all your heavy lifting in the managed classes outside of the forms... which work just like your regular c++ classes...
cheers!
** You don't need to use managed code! if your getting problems with it, just remove 'ref' before class name

Lazy generic delegate initialisation using Ninject

I'm using Ninject 1.0 and would like to be able to inject lazy initialisation delegates into constructors. So, given the generic delegate definition:
public delegate T LazyGet<T>();
I'd simply like to bind this to IKernel.Get() so that I can pass a lazy getter into constructors, e.g.
public class Foo
{
readonly LazyGet<Bar> getBar;
public Foo( LazyGet<Bar> getBar )
{
this.getBar = getBar;
}
}
However, I can't simply call Bind<LazyGet<T>>() because it's an open generic type. I need this to be an open generic so that I don't have to Bind all the different lazy gets to explicit types. In the above example, it should be possible to create a generic delegate dynamically that invokes IKernel.Get<T>().
How can this be achieved with Ninject 1.0?
Don't exactly understand the question, but could you use reflection? Something like:
// the type of T you want to use
Type bindType;
// the kernel you want to use
IKernel k;
// note - not compile tested
MethodInfo openGet = typeof(IKernel).GetMethod("Get`1");
MethodInfo constGet = openGet.MakeGenericMethod(bindType);
Type delegateType = typeof(LazyGet<>).MakeGenericType(bindType);
Delegate lazyGet = Delegate.CreateDelegate(delegateType, k, constGet);
Would using lazyGet allow you to do what you want? Note that you may have to call the Foo class by reflection as well, if bindType isn't known in the compile context.
I am fairly certain that the only way to do this (without some dirty reflection code) is to bind your delegate with type params. This will mean it needs to be done for each individual type you use. You could possibly use a BindingGenerator to do this in bulk, but it could get a bit ugly.
If there is a better solution (a clean one) I would love to hear it as I run into this problem from time to time.
From another similar question I answered:
public class Module : NinjectModule
{
public override void Load()
{
Bind(typeof(Lazy<>)).ToMethod(ctx =>
GetType()
.GetMethod("GetLazyProvider", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(ctx.GenericArguments[0])
.Invoke(this, new object[] { ctx.Kernel }));
}
protected Lazy<T> GetLazyProvider<T>(IKernel kernel)
{
return new Lazy<T>(() => kernel.Get<T>());
}
}

Wrapping boost::function with a C++/CLI class event

I'm trying to figure out how to wrap a boost::function member (used as an event callback) of an unmanaged class with a C++/CLI class event. I do not have control over the unmanaged class. All I can do is figure out how to write the C++/CLI class properly.
Here's the example unmanaged class:
class X
{
public:
boost::function<void (double)> XChanged;;
void Set(double x)
{
XChanged(x)
}
};
I've tried many things, but I keep running into problems. I'm sure it's easier than it appears to be. Any help would be greatly appreciated!
CLI probably won't let you declare a boost::function as a static member. Make it a pointer:
boost::function<void(double> *XChanged;
Then allocate/deallocate in the constructor and finalizer and call it with (*XChanged)(arg);

Resources