- Home /
Objective c API to use in Unity3d (retaining the object-orientation)
So I am implementing an API in objective-c that I want to use then with unity. All the solutions for this task, calling objective-c from c#(unity), that I find around show how to do simple calls from c# to objective-c using an intermediate c-wrapper around the objective-c code, like this or this. Nevertheless, these simple calls eliminate the object-orientation character of the objective-c API.
To be more precise as to what I mean, lets say I have in my objective-c API a class:
@interface MyVector:NSObject
...some init methods here...
-(MyVector*)crossProduct:(MyVector*);
@end
in order to call the crossProduct
method from the c# code, the way described in the above posts, a possible c-wrapper would could look like:
//say myVector_c is a c struct
extern "C" void crossProduct_c(myVector_c* v1, myVector_c* v2, myVector_c* v_result){
MyVector* v1_objc=[[MyVector alloc] initWithx:v1.x andy:v1.y andz:v1.z];
MyVector* v2_objc=[[MyVector alloc] initWithx:v2.x andy:v2.y andz:v2.z];
MyVector* v_result_objc=[v1_objc crossProduct:v2_objc];
v_result.x=v_result_obj.x;
v_result.y=v_result_obj.y;
v_result.z=v_result_obj.z;
}
This means that in order to use the cross product functionality from the unity, c# code, one (probably...) needs to do something like
using System.Runtime.InteropServices;
public class testScript : MonoBehaviour {
...
//import the myVector_c struct
[System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void crossProduct_c(myVector_c*,myVector_c*,myVector_c*);
//and now (fingers crossed...) the cross product functionality is available through
//the crossProduct_c function
}
Now this approach seems ugly and redundant to me. It would be really nice to be able to somehow have access to the MyVector
object and its already implemented functionality in the objective-c code in a more straight forward way. What I mean is that it would be really nice to implement the c-wrapper in a way that something like:
MyVector v1=new MyVector();//or maybe MyVector* v1...
MyVector v2=new MyVector();
MyVector vResult=v1.crossProduct(v2);
could work in the C# code, without reimplementing MyVector in c# code from the "functional" implementation of the c-wrapper. What I mean is if you could do, in c#, something like:
class MyVector_csh{
MyVector v;
public MyVector_csh(){
v=new MyVector();
}
}
or something similar but without loosing the object orientation because of the intermediate c-wrapper.
So searching a bit more I have found approaches to wrap c++ code inside c code using c-structs to "imitate" the object-orientation of c++ code, like this. Without being 100% sure that I understand the approach it seems to me that this would be a neater approach to "forward" calls from c# to objective-c objects. Not sure though how and if an approach like that could work for wrapping the objective-c (instead of c++) inside c code.
So my question is, to people that have more experience than me on mixing different languages (and at the same time admirers of object orientation concepts), first if an approach like that makes sense, and if yes could someone put up some code as to how this last part could work with objective-c, and if what I am saying makes no sense maybe someone could propose another approach, because the design of an elegant way to deal with the objective-c classes from the c# code has become a heavy headache for me the last few days...
Thanks!
Answer by Sisso · Sep 26, 2013 at 11:51 AM
In general case language interoperability it is a very dangerous ground. Everything get much more complex when you call from differente languages. This is the main reason that you generally only do few calls to static methods and use basic variables. (http://en.wikipedia.org/wiki/Facade_pattern)
Some languages could have better interoperability like object-c with C# or java with Scale. But even then, it is better to use the same principles, a single wrong delete (or wrong garbage collector from C#) could ruin your day.
In the case that you really want to do It, it is better to use facade on each side and use yours wrapper classes to give a more meaningful code. It is very common solution when you want to give a better API for a high level language from a low level library. Like create a wrapper for Box2D for scala.
Your answer
Follow this Question
Related Questions
How to use an xcode game on unity3d 0 Answers
Cloud recognition in Vuforia 0 Answers
"Cannot use '@try' with Objective-C exceptions disabled" Error 1 Answer
problem plugin 0 Answers