Posts

Showing posts from April, 2010

C++/CLI: Trigger Events from native code and handle them in Managed Code, part II

Spanish version / Versión en Español In the previous post, we saw how to trigger an event from a C++ native class which has a C++/CLI wrapper as an interface to .NET. We dealt with the general case in which we wish to pass non trivial information (a class or a struct) along with the event. Today we'll see the more simple case in which we just need to pass a float or some other basic CLR type. As expected, things are quite simpler. In the native class, just for convenience, define a pointer to function type. Both returnType and parameters should be basic CLR types. typedef <returnType> ( __stdcall * PFOnEventCallback )( <parameters> ); In the same class, declare a field of that type: PFOnEventCallback m_fireEvent; Still in the native class, go to where you wish to trigger the event: if (m_fireEvent) m_fireEvent( <parameters> ); (It's good practice to initialize m_fireEvent to 0 or NULL, your cho

C++/CLI: Generar eventos desde C++ y capturarlos en código manejado, parte II

Versión en inglés / English version En la entrada anterior, vimos como generar un evento desde una clase C++ nativa que tiene un wrapper C++/CLI como interfaz hacia .NET en el caso general en que deseamos pasar información extra en el evento, y dicha info no es de un tipo primitivo (o sea, un tipo que no conocen tanto C++ como .NET). Si sólo queremos pasar un float, un int, o cualquier tipo que conozcan tanto C++ como .NET, el método que vimos antes se simplifica un poco. En la clase nativa, definimos, por comodidad, un tipo puntero a función: typedef <retorno> ( __stdcall * PFOnEventoCallback )( <parametros> ); En la misma clase, declaramos un atributo del tipo definido en 1): PFOnEventoCallback m_FireEvento; Dentro de la clase nativa, donde querramos disparar el evento: m_FireEvento( <parametros> ); (Es buena idea inicializar m_FireEvento en NULL y validar que sea distinto de NULL antes de hacer el fir

C++/CLI: Trigger events from C++ native code and handle them in Managed code, Part I

Spanish version / Versión en Español Imagine we want to trigger an event from a native class which has a C++/CLI wrapper as an interface to managed code (C#, VB.NET). And let's deal with the general case in which we desire to pass extra information along with the event, and said information is not inside a CLR basic type, that is one which both native and managed C++ understand (int, float, char, and so on). In the native class, declare, just for convenience, a pointer to function type: typedef <nativeReturnType> ( __stdcall * PFOnEventCallback )( <nativeParameters> ); Still in the native class, declare a field of the type declared in 1): PFOnEventCallback m_fireEvent; In the place in the native class where we want to trigger the event: if( m_fireEvent ) m_fireEvent( <nativeParameters> ); (This suggests you to initialize m_fireEvent to 0, or NULL if you prefer) Now we need a setter for m_

C++/CLI: Generar eventos desde C++ y capturarlos en código manejado, Parte I

Versión en inglés / English version Supongamos que queremos generar un evento desde una clase C++ nativa que tiene un wrapper C++/CLI como interfaz hacia .NET. Supongamos el caso general en que deseamos pasar información extra en el evento, y dicha info no es de un tipo primitivo (o sea, un tipo que no conocen tanto C++ como .NET). En la clase nativa, definimos, por comodidad, un tipo puntero a función: typedef <retornoNativo> ( __stdcall * PFOnEventoCallback )( <parametrosNativos> ); En la misma clase, declaramos un atributo del tipo definido en 1): PFOnEventoCallback m_FireEvento; Dentro de la clase nativa, donde querramos disparar el evento: m_FireEvento( <parametrosNativos> ); (Es buena idea inicializar m_FireEvento en NULL y validar que sea distinto de NULL antes de hacer el fire) Ahora debemos exponer un setter para este atributo, de este estilo: void CClaseNativa::registerOnEvento

C++/CLI: Native types visibility/access

Spanish version / Versión en Español Say we have the following code in a C++/CLI assembly: //Assembly A public ref class ManagedClass{ public: ManagedClass( const NativeClass &a ); } If we wish to invoke this constructor from another C++/CLI assembly, as in this case... //Assembly B ManagedClass^ AnotherManagedClass::Property::get(){ NativeClass temp; return gcnew ManagedClass( temp ); } ... when we try to compile Assembly B, we'll get a compile error saying that the constructor we're trying to call is private. But how is that possible, if we declared it public? The answer is here . To sum it up, the workaround is using the #pragma make_public(NativeClass) directive right below the #include for NativeClass. This makes NativeClass accesible to other C++/CLI assemblies.

C++/CLI: Visibilidad/acceso de tipos nativos

Versión en inglés / English version Supongamos que tenemos lo siguiente en una assembly C++/CLI: //Assembly A public ref class ManagedClass{ public: ManagedClass( const NativeClass & a ); } Si quiero invocar ese constructor desde otra assembly, por ejemplo... //Assembly B ManagedClass^ AnotherManagedClass::Property::get(){ NativeClass temp; return gcnew ManagedClass( temp ); } ...al tratar de compilar Assembly B, nos saltará un error en tiempo de compilación que dirá que el constructor que estamos invocando es privado. ¿Pero cómo puede ser si lo declaramos público? La respuesta está acá . Allí vemos que la solución consiste en usar la directiva #pragma make_public(NativeClass) justo debajo del #include de NativeClass.