Friday, April 8, 2011

How to create a global handle in C++

I am trying to use a C# class in a C++ project, but Visual Studio will only let me declare a handle (^) to a C# object in a local scope, just inside a function. The only way I got it working was declaring a global pointer to a handle:

SUTAdapter::Form1^ *ptForm1;

But if then I create an object inside a function and give its address to the global pointer:

SUTAdapter::Form1^ form1;
form1 = gcnew SUTAdapter::Form1();
ptForm1 = &form1;
(*ptForm1)->incCounter(0);

When the function exits and I try to use the incCounter function inside some other C++ function, the object seems gone (debugger says this == null). Is there a way to have a global handle of a C# code in C++? I guess global handles are forbidden for some reason I don't understand but I am out of ideas and I need this done. Thank you.

edit:

*ptForm1 = gcnew SUTAdapter::Form1();

Gives a null reference exception. Why?

From stackoverflow
  • I think - and that's without testing it - that the problem you're having is because you're storing a pointer to a local handle, which might confuse the garbage collector a little due to the fact that you're taking a pointer to an automatic object.

    Have you tried to replace the above assignment with

    
    *ptForm1 = gcnew SUTAdapter::Form1();
    

    instead of the detour via the local object reference?

    Hiperi0n : It throws a null reference exception.
    Timo Geusch : Ah yes, now that you mention it it's quite obvious. I would assume that you'd have to initialise it with a Form^1 reference first, but again I haven't tried that and you appear to have found the proper solution anyway.
  • Will Visual Studio let you declare a static handle to a C# object in a local scope?

    SUTAdapter::Form1^ theForm() {
       static SUTAdapter::Form1^ form1 = gcnew SUTAdapter::Form1();
       return form1;
    }
    
  • Ok thanks for your answers but I finally solved it, I found it googling:

    http://bytes.com/groups/net-vc/473036-how-define-global-com-object-vc-8-a

    It seems that VS doesn't let global handles or static handles inside functions. I am puzzled about this because sometimes it is necessary to access managed objects globally.

    The solution is to declare a "GlobalObjects" class with static handles inside it:

    ref class GlobalObjects
    {
    public:
    static SUTAdapter::Form1^ hndForm1;
    };
    

    This way I can access the C# form/class globally. The error code of the previoous error is C3145, I am still wondering why does not VS allow the declaration of global handles.

  • *ptForm1 = gcnew SUTAdapter::Form1();
    

    Gives a null reference exception because you are dereferncing a null pointer - it is just like a pointer to any other type in that regard.

  • This restriction seems consistent with the other CLR-based languages. C# has no concept of a static, function-scoped variable for example. The lack of such functionality in C++/CLI suggests that is the way the CLR works - static objects must be defined at the class scope.

    The CLR is object based, so this is just a case of that object-oriented nature influencing the design of languages that run on top of it.

    From an OO view point, I like the C# way better anyway.

    Hiperi0n : Yes, having worked in C# and trying to do some basic things in C++ can be a real pain.

0 comments:

Post a Comment