Skip to content

Instantly share code, notes, and snippets.

@macmade
Last active March 15, 2023 10:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macmade/c69294418961656573efe393baf275e1 to your computer and use it in GitHub Desktop.
Save macmade/c69294418961656573efe393baf275e1 to your computer and use it in GitHub Desktop.
objc_msgSend - C++ Lambda
#include <functional>
#include <iostream>
#include <objc/runtime.h>
#include <objc/message.h>
template< typename _R_, typename ... _T_ >
_R_ CXX_IMP( id self, SEL _cmd, _T_ ... args )
{
Class cls;
id assoc;
std::function< _R_( _T_ ... ) > * f;
std::cout << "CXX_IMP: " << self << std::endl;
cls = object_getClass( self );
if( cls == nullptr )
{
return;
}
assoc = objc_getAssociatedObject( reinterpret_cast< id >( cls ), _cmd );
if( assoc == nullptr )
{
return;
}
f = reinterpret_cast< std::function< _R_( _T_ ... ) > * >( assoc );
( *( f ) )( std::forward< _T_ >( args )... );
}
int main( void )
{
Class cls;
cls = objc_allocateClassPair( objc_getClass( "NSObject" ), "Foo", 0 );
if( cls == nullptr )
{
return EXIT_FAILURE;
}
if( class_addMethod( cls, sel_registerName( "test" ), reinterpret_cast< IMP >( CXX_IMP< void, int > ), "" ) == false )
{
return EXIT_FAILURE;
}
objc_setAssociatedObject
(
reinterpret_cast< id >( cls ),
sel_registerName( "test" ),
reinterpret_cast< id >
(
new std::function< void( int ) >
(
[]( int x )
{
std::cout << x << std::endl;
}
)
),
OBJC_ASSOCIATION_ASSIGN
);
objc_registerClassPair( cls );
{
id o;
o = objc_msgSend( reinterpret_cast< id >( cls ), sel_registerName( "alloc" ) );
o = objc_msgSend( o, sel_registerName( "init" ) );
objc_msgSend( o, sel_registerName( "test" ), 42 );
objc_msgSend( o, sel_registerName( "release" ) );
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment