Page 2 of 10

Re: C interface as core feature

Posted: Tue Feb 15, 2011 1:49 pm
by so0os
Thanks a bunch ;)
I guess you're right about the auto-completion stuff.
Also, I would suggest to omit class indicator, where applicable. For example set_position() would point to Node::setPosition(), and even tho this one is used i Camera too, I guess Node should have a priority here.

Doing this automatically could probably keep it shaped more like Ogre, but would be mostly useless (as in utterly inefficient to work with).

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:03 pm
by betajaen
What about?

Code: Select all

void set_position(Node*);
void set_position(Camera*);
Vector3 get_position(Node*);
Vector3 get_position(Camera*);

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:05 pm
by jacmoe
That's not valid ANSI C, I'm afraid.. :)
It doesn't know how to overload.
I am trying to keep it strictly C99 compatible.

But you can do:

Code: Select all

void set_position(int object_handle);
vect3 get_position(int object_handle);

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:08 pm
by jacmoe
But, maybe 'camera_do_stuff', 'node_do_stuff' is faster because then we don't have to look things up.
I guess we can have both. :wink:

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:10 pm
by jacmoe
so0os wrote:Also, I would suggest to omit class indicator, where applicable. For example set_position() would point to Node::setPosition(), and even tho this one is used i Camera too, I guess Node should have a priority here.
I think we could have a special set_position function, in addition to the more specific type_set_position functions.
That's a good idea.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:19 pm
by betajaen
jacmoe wrote:That's not valid ANSI C, I'm afraid.. :)
It doesn't know how to overload.
I am trying to keep it strictly C99 compatible.

But you can do:

Code: Select all

void set_position(int object_handle);
vect3 get_position(int object_handle);
Ahh, I didn't know that.

How are you handling the handles; are they just pointers casted to ints? Or do you have them in a stl::map say?

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:19 pm
by so0os
Overloads are not allowed in C, but we can workaround this using void* handles (like WinAPI), that will save us tons of typing when it comes to inheritance, e.g.

Instead of having node_stuff and bone_stuff,, we'll have just stuff, so that the followingwould call the appropriate method:

Code: Select all

void stuff(void* node_or_bone_or_tagpoint_ptr)
{
  (Node*)node_or_bone_or_tagpoint_ptr->stuff();
}
This way we would only have to implement wrappers for methods that don't appear in parent class, and use defines for conviency.

EDIT: you guys type too fast

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:21 pm
by jacmoe
betajaen wrote:How are you handling the handles; are they just pointers casted to ints? Or do you have them in a stl::map say?
I am not handling them yet. :D
Just saw that Horde3D uses that, so I thought it would be added.
I think they're using a map.

About C99:
Well, make that C90 instead. VC doesn't do C99 yet.. :(

<edit>@so0os:
Yes. :)
Void pointers are also a good option.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:26 pm
by so0os
I guess we shouldn't manage emitted handles at all. At least I don't see why the wrapper should do this.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:31 pm
by betajaen
Interesting, I'll have to change some things in my C API.

What about some of the inheritance classes; i.e. Node/SceneNode, I believe I read somewhere that C doesn't support them, and would be calling the wrong functions. Is this handled automatically via the C++ compiler, or what is the correct solution?

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:36 pm
by so0os
betajaen wrote:Interesting, I'll have to change some things in my C API.

What about some of the inheritance classes; i.e. Node/SceneNode, I believe I read somewhere that C doesn't support them, and would be calling the wrong functions. Is this handled automatically via the C++ compiler, or what is the correct solution?
Yeah, the wrapper is written in C++ using C calls, so it handles this automagically, and the code I posted would work just fine for Node/SceneNode/Bone/TagPoint
so0os wrote:

Code: Select all

void stuff(void* node_or_bone_or_tagpoint_ptr)
{
  (Node*)node_or_bone_or_tagpoint_ptr->stuff();
}

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:52 pm
by jacmoe
betajaen wrote:Interesting, I'll have to change some things in my C API.
Would be a good idea to test your API in a small C console app.
If you're using Visual Studio, just use main.c (extension .c) and it should use the C compiler.
You will get errors if you include C++ stuff, like namespaces, classes, etc.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 2:56 pm
by so0os
jacmoe wrote: If you're using Visual Studio, just use main.c (extension .c) and it should use the C compiler.
If not, there's a 'Compile as' setting in source config dialog under C++->Advanced.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 3:00 pm
by betajaen
Hmm. That's just the headers need to be C compliant surely? If you start involving the Ogre source in the body of the function then your back in C++ again.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 3:05 pm
by so0os
Yup, headers need to be extern "C" {} in C++. I've succesfully done that with RakNet, and it just works.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 3:07 pm
by betajaen
Which I'm doing now. ;)

Re: C interface as core feature

Posted: Tue Feb 15, 2011 3:31 pm
by Chris Jones

Code: Select all

void stuff(void* node_or_bone_or_tagpoint_ptr)
{
  (Node*)node_or_bone_or_tagpoint_ptr->stuff();
}
That's a bit dangerous isn't it? You'd have to guarantee that the pointer is a Node* and not to another class, e.g. if the pointer was actually point to a bone, it shouldn't be converted directly to a Node* (it would need to be cast to a Bone* and then to a Node*).

I haven't done much C, but shouldn't these functions have a prefix of ogre_ so they don't conflict with any other functions from other libraries?

Re: C interface as core feature

Posted: Tue Feb 15, 2011 3:41 pm
by so0os
virtual method pointers are stored along with class members in a virtual function pointer table ( _vfptr[] ), so as long as the pointer is valid, and no-one memset it to 0, the code will work. It's perfectly safe.

About the prefix, I guess we could leave that option to user via a define adn forgotten ## operator.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 4:09 pm
by Chris Jones
virtual method pointers are stored along with class members in a virtual function pointer table ( _vfptr[] ), so as long as the pointer is valid, and no-one memset it to 0, the code will work. It's perfectly safe.
IIRC The address of a pointer to a class isn't nessesarily the same as a pointer to its base class, casting between pointer types actually offsets the address. If you've got a void* it won't know how to offset it correctly so you'll end up with an invalid pointer. I might be wrong though, it's been a while since i've used C/C++.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 4:24 pm
by so0os
It's called polymorphism and works ;) Also, the offset doesn't matter, the wrapper doesn't deal with memory managemnent.

Anyways, this is getting off topic, let's not talk about it.

Re: C interface as core feature

Posted: Tue Feb 15, 2011 4:28 pm
by Kojack
Ogremain has 946 types and 9052 methods (16023 if we count plugins too), it could take a while to wrap them all. :)
(CppDepend is a great program, performing sql queries on c++ source is cool)

Re: C interface as core feature

Posted: Tue Feb 15, 2011 4:35 pm
by jacmoe
The whole point of this is to create an interface, not a one to one mapping.
The latter is what tools like SWIG is for: generate and don't look at the results.

With proper abstraction and careful design, it's actually doable. :)

Re: C interface as core feature

Posted: Tue Feb 15, 2011 4:55 pm
by Chris Jones
(Sorry, i'll stop posting about this now)

From http://www.codeproject.com/KB/cpp/static_cast.aspx:
Once we have cast the pointer to void*, we can't cast it back to the original class easily. In the above example, the only way to get back a CDerived* from a void* is to cast it to a CBaseY* and then to CDerived*. But if we are not sure whether it is CBaseY* or CDerived*, then we have to use dynamic_cast<> or typeid [2].

Re: C interface as core feature

Posted: Tue Feb 15, 2011 7:41 pm
by jacmoe
You are not off-topic Chris. :)

In fact, I implemented this:

Code: Select all

    coiCameraHandle myCamera = create_camera("mycam");
  
    camera_set_position(myCamera, 0, 0, 80);

    camera_lookat(myCamera, 0, 0, -300);
'coiCameraHandle' is referring to a void pointer, but it's 'type safe', using the same trick as So0os mentioned:

Code: Select all

#define COI_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
And in the header:

Code: Select all

COI_DECLARE_HANDLE(coiCameraHandle);
...
DLL coiCameraHandle create_camera(const char* name);
DLL coiCameraHandle get_camera(const char* camera_name);
DLL void camera_set_near_clip_distance(coiCameraHandle camera_handle, coiReal d);
In the C++ code:

Code: Select all

DLLEXP coiCameraHandle create_camera(const char* camera_name)
{
    Ogre::Camera* camera = Ogre::Root::getSingletonPtr()->getSceneManager("scene-manager")->createCamera(camera_name);
    return (coiCameraHandle)reinterpret_cast<void*>(camera);
}

DLLEXP void camera_set_near_clip_distance(coiCameraHandle camera_handle, coiReal d)
{
    Ogre::Camera* camera = reinterpret_cast<Ogre::Camera*>(camera_handle);
    camera->setNearClipDistance( d );
}
I stole it from Bullet! :D

Other handles needs to be created: coiEntityHandle, coiWhatevarHandle..
It's actually neat. :wink:

Re: C interface as core feature

Posted: Tue Feb 15, 2011 9:08 pm
by jacmoe
It doesn't work in VC.
I hate that compiler..