Passing a C++ method to an Objective-C method - c++

I have a C++ class 'Expression' with a method I'd like to use in my Objective-C class 'GraphVC'.
class Expression {
double evaluate(double);
}
And my Objective-C class:
#implementation GraphVC : UIViewController {
- (void)plot:(double(*)(double))f;
#end
I thought that it would be easiest to pass around function pointers that take a double and return a double, as opposed to C++ objects, but I haven't had much success using functional.h. What's the best way to use my C++ method from Objective-C?
EDIT: Thanks for your quick responses. Allow me to elaborate a bit... I have a backend written in C++ where I manipulate objects of type Expression. There's subclasses for rational, polynomial, monomial, etc. My initial idea was to use mem_fun from , but I wasn't able to get code compiling this way. I also had trouble using bind1st to bind the this pointer.
Writing an Objective-C wrapper is a possibility, but I'd rather use the already existing evaluate() function, and I don't want to break the clean separation between the backend and the iPhone GUI classes.
I can't have a global expression or use a static method (I need to plot arbitrary Expression instances.
I should have more explicitly stated that I need to pass a C++ member function (not a static function or existing C function) to an Objective-C object. Has anyone had luck using C++'s <functional> to turn member functions into pointers I can use in an Objective-C object, or should I use an Objective-C wrapper?

If you want to make a pointer to a method in C++, you need to include the class name, like this:
class Foo
{
public:
double bar(double d)
{
return d;
}
};
void call_using_obj_and_method(Foo *f, double (Foo::*m)(double d))
{
(f->*m)(3.0);
}
int main()
{
Foo f;
call_using_obj_and_method(&f, &Foo::bar);
return 0;
}
Note that you need an instance of the class as well. In my example this is another parameter, though you could let it be a global variable, or a singleton instance of class Foo.
Though, like jkp said, you can also solve the problem by making the method static or turning it into a regular function.
EDIT: I'm not sure if I understand your question correctly. I don't think you need to use functional. Here is how my example would look in Objective-C++:
#include <Cocoa/Cocoa.h>
class Foo
{
public:
double bar(double d)
{
return d;
}
};
typedef double (Foo::*fooMethodPtr)(double d);
#interface Baz : NSObject
{
}
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m;
#end
#implementation Baz
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m
{
(f->*m)(3.0);
}
#end
int main()
{
Foo f;
Baz *b = [[Baz alloc] init];
[b callFooObj:&f method:&Foo::bar];
return 0;
}

I would suggest wrapping the C++ class in an Objective-C class, and then also providing a
- (void) plotWithObject:(id)obj
{
double result = [obj evaluate: 1.5];
// ... etc ...
}
in addition to the plot: method.

I think the problem here is that you are trying to pass a member function of your Expression class to the Objective-C class. This will not work because it's expecting a this pointer as the first argument to that function (therefore the signature is not the same as the one expected by the plot: method.
If you make the C++ method a static, you can do this, but then you don't buy yourself a lot over using a standard C function.
IE, if the Expression class looked like this:
class Expression {
static double evaluate(double);
}
You should be able to call it like this:
[self plot:myExpression.evaluate(&Express::evalulate)];
As I say though, there isn't a huge amount of value in this because you may as well be using a standard C function (unless you can do something in the C++ class that is more useful to you).
I did once look at trying to bridge boost::bind() results with objective-c methods but didn't get very far. I'm sure if you dig deep enough in the C++ runtime you could do it though.

If your C++ member function returns a double, can't your code just look like this?
- (void)plot:(double)f;
...
[self plot:myExpression.evaluate(aDouble)];
Or something similar. I've not used much mixing of Obj-C and C++, but this is how I would approach it. You also might have to have a .mm extension on your Objective-C++ file if you're mixing them like that.

Why wouldn't you pass the instantiated c++ class around inside an NSValue and then call the c++ method directly?
- (NSValue*)getExpression
{
Expression* e = new Expression();
return [[NSValue alloc] initWithPointer:e];
}
- (void)callExpression(NSValue*)expression
{
Expression* e = [expression pointerValue];
e->evaluate();
}

Related

Pointer to function from another pointer

I'm new to c++ and I'm trying to make a generic switch (i.e. the device, not the C++ statement) that could be used to blink lights, turn beeps on and off, etc, in my Arduino project.
I could create a switchable interface and implement that in the classes that I want to "switch". But since I'm doing it as study purposes and I saw the pointer-to-functions ability in C++ (that is new to me since I come from C# and Java), I tough it would be a good opportunity to give it a try...
The problem is that I can pass the function in my code only if it's a local function but it won't work if I try to pass a function from another object like a led for example.
Some code to illustrate the problem. This is the switch.cpp, it recieves the On and Off functions in it's constructor and it has a update method that is called inside the loop method in the Arduino ino main class:
auto_switch.cpp
using switch_function = void(*)();
auto_switch::auto_switch(const switch_function on_function, const switch_function off_function, const int max_speed_count)
{
//sets all variables...
}
void auto_switch::update(const unsigned long millis)
{
//turn switch on and off...
}
And this is my ino file
ino file
#include <Arduino.h>
#include "led.h"
#include "auto_switch.h"
led* main_led;
auto_switch* led_switch;
int slow_speed;
//ugly code
void turn_led_on()
{
main_led->turn_on();
}
//ugly code
void turn_led_off()
{
main_led->turn_off();
}
void setup() {
main_led = new led(2, 3, 4, true, color::white);
//ugly code
led_switch = new auto_switch(turn_led_on, turn_led_off, 3);
slow_speed = led_switch->add_speed(100, 100, 3, 1000);
led_switch->set_active_speed(slow_speed);
led_switch->turn_on();
}
void loop() {
led_switch->update(millis());
}
It works but I had to make a local function (turn_led_on and turn_led_off) to be able to assign the inner functions as a parameter to the auto_switch constructor, the parts that I've wrote //ugly code
I wanted to do something like this, without the glue code in between:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
Is it possible? I've read something about static pointer to function and some std functions that help with that, if I get it right the glue code is necessary in this case so that the compiler can know where the functions are coming from I guess (from which object), but since the functions I need to call cannot be static I've discarded this option, and the std functions I believe it can't be used with the Arduino or could but shouldn't for performance limitations...
Anyway, does it make sense, can it be done using pointer to functions or should I create a interface or something different?
Before deciding how to do it, the qquestion is what do you want to do and why. Because, maybe there are better alternatives using simple C++ idioms.
Option 1: specialization with polymorphism
Do you want to specialize some functions of your switch, so instead of calling the function of the auto_switch you'd call dome more specialized ones ?
In this case you wouldn't do:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
but instead you would rely on polymorphism with virtual functions in the base class:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
and write a specialized class for the leds:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
In fact, the compiler will generate some function pointers behind the scene, but you don't have to care:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
But event if each object's behavior is dynamic on the the base of the real class of the object, the objects of the same class share a behavior that was predefined at compile time. If this is not ok, go to the next option.
Option 2: the member function pointer
The functions of another objects can only be invoked with that object at hand. So having a function pointer to a led function is not sufficient: you also need to know on which led it shall be applied.
This is why member function pointers are different and somewhat constraint: you can only invoke functions of class of your member function pointer. If polymorphism is sufficient (i.e. if derived class has a different implementation of a function already foreseen in the base classe) then you are lucky. If you want to use a function that only exists in the derived class and not in the base class, it won't compile.
Here a simplified version of auto_swith: I provide a function, but allso a pointer to the object on which the function has to be invoked:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Online demo
Option 3 : the functional way (may that's what you're looking for ?)
Another variant would be to use the standard functional library to bind a member function and the object on which it shall be executed (as well as any need parameters):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Here you can bind anything: any function of any class:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Online demo
Option 4 : command pattern
Now if you want to perform something on an object when you turn on and off the switch, but you need total flexibility, you can just implement the command pattern : this lets you execute anything on any object. And you don't even need a function pointer.

Is there a way to pass function from objective-c++ to standard c++?

I want to pass objective-c++ function pointer to standard c++ so that I can call objective-c method on C++.
Here is what I want to achieve:
//C++ side
class CppSide
{
public:
void(*TestFunction)();
};
//objective-c++ side
#interface InteropController : GLKViewController{
}
-(void) PickFile; //I want to pass PickFile address to TestFunction
#end
Following is what I did, but doesn't work
InteropController* controller = [[InteropController alloc] init];
CppSide* cppSide = new CppSide();
cppSide->TestFunction = [controller methodForSelector:#selector(PickFile:)];
cppSide->TestFunction(); //EXC_BADccess(code=1, address=0x2d)
How should I do?
The lazy, easy way is to pass an std::function that calls the objC code (eg, with a lambda).
However, what you have there is a raw C function pointer. You will need to write a C function (or use a non-capturing lambda):
cppSide->TestFunction = [](){ ... ObjC Code here ...};
However, you have no way of referring to the parent scope there - only to the global scope.
If you can change that instead to use an std::function, you will have much more flexibility:
cppSide->TestFunction = [=](){[controller PickFile: ... ];};
If you can't, for some reason, change that function pointer type, consider changing it so that it at the very least expects a data pointer:
class CppSide
{
public:
void(*TestFunction)(void *data);
};
And then you can do:
cppSide->TestFunction = [](void *data) {
InteropController* controller = static_cast<InteropController*>(data);
[controller PickFile: ... ];
}
The caller that invokes the function pointer then needs to explicitly pass a controller.

Is there C++ equivalent of Objective-C Instance and Class Methods?

I am learning C++ with Xcode (cocos2d-x).
A regular c++ void method I think is equivalent to an obj-c -void Instance method.
Is there is a c++ equivalent of the obj-c +void Class method?
Thanks
There is no direct equivalent to class methods in C++; however, in many cases C++ static methods can be used in place of class methods.
For example, this Objective-C code:
#interface MyClass : NSObject
{
int _number;
}
+ (MyClass*)newInstance;
- (void)instanceMethod;
#end
#implementation MyClass
+ (MyClass*)newInstance
{
return [[self alloc] init];
}
- (void)instanceMethod
{
_number = 123;
std::cout << _number;
}
#end
int main(void)
{
MyClass* foo = [MyClass newInstance];
[foo instanceMethod];
return 0;
}
is roughly equivalent to this C++ code:
class MyClass
{
int _number;
public:
static MyClass* newInstance();
void instanceMethod();
};
MyClass* MyClass::newInstance()
{
return new MyClass();
}
void MyClass::instanceMethod()
{
_number = 123;
std::cout << _number;
}
int main(void)
{
MyClass* foo = MyClass::newInstance();
foo->instanceMethod();
return 0;
}
That example also illustrates one of the differences between class methods and static methods.
+newInstance will be inherited by subclasses and will always work correctly (it will always return an instance of a subclass). It can also be overridden by a subclass.
Static methods like MyClass::newInstance() cannot be inherited or overridden. It will always return an instance of MyClass.
So when you're porting code between Objective-C and C++ there are cases when you cannot use static methods in place of class methods. But for most cases, C++ static methods are a fine replacement.
class SomeClass {
public:
static void someMethod();
};
The equivalent of class methods in C++ would be static functions.
static return_type function_name(parameters);
Just like in Objective-C, in static functions you cannot reference instance variables (since there's no instance), only static variables.
For example.
class A{
public:
static void doIt();
};
Then you can call function doIt with:
void main()
{
A::doIt();
}
Objective-C has implicit metaclasses as explored in "What is a meta-class in Objective-C?" article. The full power of metaclasses is not unleashed, however. It would require multiple inheritance support and other technical decisions, as described in famous "Putting Metaclasses to Work" book. That was probably too complex for Objective-C authors, so they decided to hide metaclasses in Objective-C.
Objective-C targets Objective-C runtime (obj.dll or libobjc.dylib), and there were C++ compilers (DTS C++, Direct-to-SOM C++) targetting SOM the same way. This makes DTS C++ closer to Objective-C than C++ in its design. I managed to get old Windows DTS C++ compiler running on Windows 8 this way:
Download VAC 3.5 fixpak 9 from IBM FTP. This fixpak contain many files, so you don't even need to full compiler (I have 3.5.7 distro, but fixpak 9 was big enough to do some tests).
Unpack to e. g. C:\home\OCTAGRAM\DTS
Start command line and run subsequent commands there
Run: set SOMBASE=C:\home\OCTAGRAM\DTS\ibmcppw
Run: C:\home\OCTAGRAM\DTS\ibmcppw\bin\SOMENV.BAT
Run: cd C:\home\OCTAGRAM\DTS\ibmcppw\samples\compiler\dts
Run: nmake clean
Run: nmake
hhmain.exe and its dll are in different directories, so we must make them find each other somehow; since I was doing several experiments, I executed "set PATH=%PATH%;C:\home\OCTAGRAM\DTS\ibmcppw\samples\compiler\dts\xhmain\dtsdll" once, but you can just copy dll near to hhmain.exe
Run: hhmain.exe
I've got an output this way:
Local anInfo->x = 5
Local anInfo->_get_x() = 5
Local anInfo->y = A
Local anInfo->_get_y() = B
{An instance of class info at address 0092E318
}
This example does not use metaclasses, it's just for checking DTS C++ compiler.
Metaclasses in SOM are explicit, thus so called "class methods" are no more than "instance methods" of metaclass. Each object belongs to some class, managed by so called class-object created in runtime. Class-object is itself an instance of another class, named metaclass. Developer of a class can specify metaclass constraint via IDL or DTS C++ pragma.
If one needs to call method of known at compile time class, one can just reference class-object and invoke its method just like ordinary object which class-object is in essence. Class-object is being referenced via DLL import/export mechanisms, similar to Objective-C.
If one needs to invoke a method of a class that object is belonging to, one needs to invoke somGetClass() to get class-object, typecast it to metaclass type and invoke desired method. In DTS C++ one should probably not need to do redundant typecasting, but I am not expert in IBM DTS C++ properties.

calling methods in cpp like #selector(someMethod:) in Objective-C

In Objective-C you can pass a method A as a parameter of other method B.
and call method A from inside method B
very easily like this:
-(void) setTarget:(id)object action:(SEL)selectorA
{
if[object respondsToSelector:selectorA]{
[object performSelector:selectorA withObject:nil afterDelay:0.0];
}
}
Is there any functionally like this in C++ ?
C++ and Objective-C are quite different in that regard.
Objective-C uses messaging to implement object method calling, which means that a method is resolved at run-time, allowing reflectivity and delegation.
C++ uses static typing, and V-tables to implement function calling in classes, meaning that functions are represented as pointers. It is not possible to dynamically determine whether a class implements a given method, because there are no method names in memory.
On the other hand, you can use RTTI to determine whether a given object belongs to a certain type.
void callFunc(generic_object * obj) {
specific_object * spec_obj = dynamic_cast<specific_object*>(obj);
if (spec_obj != NULL) {
spec_obj->method();
}
}
Edit:
As per nacho4d's demand, here is an example of dynamic invocation :
typedef void (specific_object::*ptr_to_func)();
void callFunc(generic_object * obj, ptr_to_func f) {
specific_object * spec_obj = dynamic_cast<specific_object*>(obj);
if (spec_obj != NULL) {
((*spec_obj).*f)();
}
}
Yes there is, and they are called "Function Pointers", you will get lots of results googling around,
http://www.newty.de/fpt/index.html
http://www.cprogramming.com/tutorial/function-pointers.html

How to determine if a C++ usertype has been registered with tolua

We use tolua++ to generate Lua bindings for C++ classes.
Assume I have a C++ class:
class Foo
{
//Some methods in Foo, irrelevant to question.
};
and a tolua .pkg file with the following contents
class Foo
{
};
Consider the following function:
void call_some_lua_function(lua_State* luaState)
{
Foo* myFoo = new Foo();
tolua_pushusertype(luaState, (void*)myFoo, "Foo");
//More code to actually call Lua, irrelevant to question.
}
Now, the actual question:
tolua_pushusertype causes a segfault in Lua if the 3rd parameter does not correspond to a valid fully qualified string of a C++ class that was registered with a call to tolua_cclass. So, if parameter 3 where "Bar", we get a segfault.
What I would like to do is the following:
void call_some_lua_function(lua_State* luaState)
{
//determine if tolua is aware of my type, how to do this?
//Something like:
//if(!tolua_iscpptype_registered("Foo"))
//{
// abort gracefully
//}
Foo* myFoo = new Foo();
tolua_pushusertype(luaState, (void*)myFoo, "Foo");
//More code to actually call Lua, irrelevant to question.
}
Is there a way to do this using tolua?
I am using tolua, not tolua++, but let's hope it is somehow similar. In tolua, you can test if the class is registered with it like this:
tolua_getmetatable(L, "ClassName");
if (lua_isnil(L, -1)) {
// the class wasn't found
}
Hint: check how tolua.cast is implemented and checks its arguments. It takes a type name as string.
Edited: More curious, I downloaded the tolua++ sources and looked inside. It doesn't look completely similar, and the critical function is missing. I have to give you an untested suggestion that might work:
luaL_getmetatable(L, "ClassName");
if (lua_isnil(L, -1)) {
// the class wasn't found
}
The difference between tolua and tolua++ seems to b that tolua uses a "namespace" for its created metatables ("tolua." prefix).
I am just a lua beginner, hence my suggestion: Wrap your tolua-calls in your own function which keeps track of the classes registered through it. Now you can ask your wrapper if tolua is aware of your class.