C interface as core feature

What it says on the tin: a place to discuss proposed new features.
Post Reply
User avatar
abenthy
Gnoblar
Posts: 1
Joined: Mon Feb 21, 2011 2:03 pm

Re: C interface as core feature

Post by abenthy »

Great project, i love the Idea and the c_style_names. :)
As far as I understand this, it will not be possible to implement this Ogre interface in pure C because of the void* handles used for C++ objects, right?
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

It *is* pure C - C90 to be precise (VC uses C90 when compiling in C - GCC uses C99). :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

GCC (3.4) needs to be told to use C99 explicitly (-C99), dunno about GCC4

Also, I'm pretty more tight on schedule than I thought and I suppose i won't be as much of a help as I would like to. It'll be nice if someone joined our forces.
Sos Sosowski :)
http://www.sos.gd
spectrumgomas
Gnoblar
Posts: 2
Joined: Wed Mar 02, 2011 10:00 am

Re: C interface as core feature

Post by spectrumgomas »

Why not use glib / gobject ?
spectrumgomas
Gnoblar
Posts: 2
Joined: Wed Mar 02, 2011 10:00 am

Re: C interface as core feature

Post by spectrumgomas »

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Thanks for the link. :)
Looks interesting.
However, I think it's going to stay hand-made - at least for now.

I am deep in the land of Lisp right now - but the project is still on. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

And I got dragged to the abyss of actionsctipt :P Will contribute soon!

PS. Flash is not that bad :P
Sos Sosowski :)
http://www.sos.gd
User avatar
JamesKilton
Halfling
Posts: 87
Joined: Tue Jun 14, 2005 8:21 pm
x 1

Re: C interface as core feature

Post by JamesKilton »

As the question on the front page concerning SWIG doesn't seem to have been answered yet I'll give the quick run-down on why I moved away from SWIG for Ogre.rb:

SWIG is really good for small wrapping projects. It's relatively easy to set up and get going and the interface file syntax isn't too cryptic, and it's well documented. However, this doesn't scale unless you really put a lot of work into it, but even then there are fundamental features missing. For those that don't know, SWIG implements it's own C++ parser using YACC, with two minor problems: it's not complete and it's not re-entrant. This means that nested structures, like those inner classes and enumerations that litter Ogre, are invisible and inaccessible. I did spend some time looking into SWIG's internals, but to update it to be re-entrant would have required almost a redesign of the entire parser structure, and I wasn't about to do that. So inspired by py++ and python-ogre I went a different direction.

SWIG 2.0 has (finally) been released, though I'm unable to find a good description of how this version is different from the 1.3 line. Maybe a lot of these problems have been addressed, I'm not sure.

To be back on topic for a bit, this entire idea is pretty awesome. It will help integrations a ton (as has been mentioned, C++ is a massive pain to try to hook into other languages) and I'll be watching this closely.

As a half-shameless-plug, instead of doing all this by hand, have you guys looked into GCC-XML for parsing the Ogre code and giving you a list of methods and enumerations to export to C? The tools pygccxml (it's website is down, strange) or rbgccxml (mine, http://rbplusplus.rubyforge.org/rbgccxml.html) make it very easy to query the XML you get back for this information and do with it what you will.
Ogre.rb Project Lead
User avatar
voyvf
Kobold
Posts: 28
Joined: Sat Jul 04, 2009 4:01 am
Location: United States
x 2
Contact:

Re: C interface as core feature

Post by voyvf »

JamesKilton wrote:As a half-shameless-plug, instead of doing all this by hand, have you guys looked into GCC-XML for parsing the Ogre code and giving you a list of methods and enumerations to export to C? The tools pygccxml (it's website is down, strange) or rbgccxml (mine, http://rbplusplus.rubyforge.org/rbgccxml.html) make it very easy to query the XML you get back for this information and do with it what you will.
If anyone decides to do this, please, please release the output of the code generation, rather than "just" the method of generating it.

The codegen issues are why I gave up on python-ogre in the first place - and opted to write my own bindings - as I need to be able to both embed and extend whichever scripting language I use. While I have a lot of respect for their project (especially after doing it by hand :wink:) it's so much easier being able to just include a couple of files, fire up an interpreter, and hook my engine into it.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Thanks for the input. :)
I'll check the gcc-xml thing.

But here's proof that the interface works with Lisp:
lispy_ogre.png
I generated the CFFI bindings using SWIG, and spent some time before I discovered that SBCL is crashing, but CCL is working.
Have no idea why Steel-Bank CL doesn't like my Ogre code - and why Clozure CL works..
But it means that I can finally move on, and expand/work-on/improve the C interface. :wink:

Here's the Lisp code btw:

Code: Select all

(require 'ogre)

(defparameter *windowhandle* nil)
(defparameter *camerahandle* nil)
(defparameter *viewporthandle* nil)
(defparameter *windowhwnd* nil)
(defparameter *entityhandle* nil)
(defparameter *nodehandle* nil)
(defparameter *lighthandle* nil)
(defparameter *mouse* nil)
(defparameter *keyboard* nil)

(ogre:create-root "plugins.cfg" "ogre.cfg" "ogre.log")

(ogre:restore-config)

(ogre:setup-resources "resources.cfg")

(setq *windowhandle* (ogre:root-initialise 1 "therenderwindow"))

(ogre:set-default-num-mipmaps 5)

(ogre:initialise-all-resourcegroups)

(ogre:create-scene-manager "OctreeSceneManager" "scenemanager")

(setq *camerahandle* (ogre:create-camera "myCam"))

(ogre:camera-set-position *camerahandle* 0.0 0.0 280.0)

(ogre:camera-lookat *camerahandle* 0.0 0.0 -300.0)

(setq *viewporthandle* (ogre:add-viewport *camerahandle*))

(ogre:viewport-set-background-colour *viewporthandle* 0.0 0.0 0.0)

(ogre:camera-set-aspect-ratio *camerahandle* 800.0 600.0)

(setq *entityhandle* (ogre:create-entity "OgreHead" "ogrehead.mesh"))

(setq *nodehandle* (ogre:create-child-scenenode "headnode"))

(ogre:attach-entity-to-scenenode *entityhandle* *nodehandle*)

(ogre:set-ambient-light-rgb 0.5 0.5 0.5)

(setq *lighthandle* (ogre:create-light "mainLight"))

(ogre:light-set-position *lighthandle* 20.0 80.0 50.0)

(ogre:log-message "Hello World from Lisp")

;;(ogre:render-window-update *windowhandle* 1)

;;(setq *windowhwnd* (ogre:render-window-get-hwnd *windowhandle*))

;;(ogre:create-input-system *windowhwnd*);

;;(setq *keyboard* (ogre:create-keyboard-object 0))

;;(setq *mouse* (ogre:create-mouse-object 0))

;;(ogre:render-one-frame)

;;(ogre:render-loop)

(let ((n 0))
    (loop
      (when (> n 4000) (return))
        (ogre:pump-messages)
        (ogre:render-one-frame)
      (incf n)))

(ogre:release-engine)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

So typical:
After banging my head on this issue for weeks - and spending the entire day on making CCL work with ASDF (Lisp package manager), I find the solution..

Code: Select all

#+sbcl(sb-ext::set-floating-point-modes :traps nil)
Now Ogre works in SBCL too. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

JamesKilton wrote:As a half-shameless-plug, instead of doing all this by hand, have you guys looked into GCC-XML for parsing the Ogre code and giving you a list of methods and enumerations to export to C? The tools pygccxml (it's website is down, strange) or rbgccxml (mine, http://rbplusplus.rubyforge.org/rbgccxml.html) make it very easy to query the XML you get back for this information and do with it what you will.
Do you have an example script for Ogre? :)
I tried running gccxml on OgreMain.h just now, and gccxml complained bitterly about gcc.4.4 tr1 stuff..
I am aware that there's a lot of flags which needs to be set - and I also spotted briefly some fixes for this issue at the python-ogre site - but a bare-bone command-line/script/whatever would help a lot.

I also found a Lispy gcc-xml generator..

BTW: when I mentioned SWIG in my pre-previous post, I meant that I use SWIG against the C interface. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
JamesKilton
Halfling
Posts: 87
Joined: Tue Jun 14, 2005 8:21 pm
x 1

Re: C interface as core feature

Post by JamesKilton »

Ya I had to follow what Python-Ogre does and actually patch Ogre's code a little bit to get around that stuff.

This is for 1.6.2, I haven't tried running against 1.7.x yet: https://github.com/jameskilton/ogrerb/b ... -6-2.patch

then run with -D__OGRERB_BUILD and the rest of the code had no problems.
Ogre.rb Project Lead
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Thanks! :)
It worked wonderfully.
Now I need to figure out what to do with the *huge* XML file it made.. :wink:
I hope that gccxml is upgraded to gcc 4.4 some day..

Would defining GCC version 420 help, I wonder?
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Yes, it did! :)
So, instead of patching all those files, we only need to patch OgrePlatform.h:

Code: Select all

#elif defined( __GNUC__ )
#   define OGRE_COMPILER OGRE_COMPILER_GNUC
#   define OGRE_COMP_VER (420)
Gcc-xml is a patched version of GCC 4.2
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
JamesKilton
Halfling
Posts: 87
Joined: Tue Jun 14, 2005 8:21 pm
x 1

Re: C interface as core feature

Post by JamesKilton »

Ah, good to know.

As for GCC-XML output, I do recommend using a library built for parsing it, as the resulting XML is probably not what you'd expect, but as I've worked with it I've found it's probably the best format for something as complicated as C++.

Basically, it's a very flat tree. The only elements with actual siblings are the root GCC-XML tag and any tag related to functions or methods (Function, Method, Operator, Constructor, etc), who's siblings are the arguments for the method. Everything else has it's scope determined by the attributes "id" and "context", and for elements with sub elements (say Namespace, Class, or Struct), the "members" attribute is a space-delimited list of the ids of said sub elements.

That should be enough to help you at least understand what the XML is saying, the rest is pretty self-explanatory.
Ogre.rb Project Lead
dermont
Bugbear
Posts: 812
Joined: Thu Dec 09, 2004 2:51 am
x 42

Re: C interface as core feature

Post by dermont »

JamesKilton wrote:Ya I had to follow what Python-Ogre does and actually patch Ogre's code a little bit to get around that stuff.

This is for 1.6.2, I haven't tried running against 1.7.x yet: https://github.com/jameskilton/ogrerb/b ... -6-2.patch

then run with -D__OGRERB_BUILD and the rest of the code had no problems.
Python-Ogre doesn't patch Ogre's code to get around the gcc-xml tr1 issue. It simply (re-)defines OGRE_COMP_VER 420 after including OgrePlatform.h in one of it's header files:

http://python-ogre.svn.sourceforge.net/ ... iew=markup

Code: Select all

#include "OgrePlatform.h"
#if (OGRE_COMPILER == OGRE_COMPILER_GNUC ) && OGRE_THREAD_PROVIDER
#define OGRE_COMP_VER 420
#endif
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

That would be an even cleaner way of doing it, I agree.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
dermont
Bugbear
Posts: 812
Joined: Thu Dec 09, 2004 2:51 am
x 42

Re: C interface as core feature

Post by dermont »

jacmoe wrote:Thanks! :)
It worked wonderfully.
Now I need to figure out what to do with the *huge* XML file it made.. :wink:
I hope that gccxml is upgraded to gcc 4.4 some day..

Would defining GCC version 420 help, I wonder?
As a first step you could take a look at the python-ogre code generators. There was some work previously to allow them to generate python Swig interface files though I don't know if that is in trunk at the moment.

You could also create your own code_generators to output the data in the format you require (see code_generators/ogre/print_classes.py) as a simple example of printing class names. I would test on a smaller module such as OIS since the code generation is quite lengthy.

You could also look at the code/documentation for pyplusplus/pygccxml.

Anyway at worst the above should you help you to at least get started with creating your own code generator.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Thanks, Dermont. :)
I'll put it on my stack of things to try out.
Verrazano (Lisp GCCXML based generator) failed bitterly on OgreRoot.h..)
I'll take a peek at the code_generators.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

I am back into the C interface binding business...
This time with a crude weapon: my homemade gccxml parser written in Lisp.
It merely extracts the public function declarations from a given Ogre class.
Like this:

Code: Select all

Ogre::MovableObject::Listener
Ogre::MovableObject::operator=(Ogre::MovableObject const&)
Ogre::MovableObject::MovableObject(Ogre::MovableObject const&)
Ogre::MovableObject::MovableObject()
Ogre::MovableObject::MovableObject(std::string const&)
Ogre::MovableObject::~MovableObject()
Ogre::MovableObject::_notifyCreator(Ogre::MovableObjectFactory*)
Ogre::MovableObject::_getCreator() const
Ogre::MovableObject::_notifyManager(Ogre::SceneManager*)
Ogre::MovableObject::_getManager() const
Ogre::MovableObject::getName() const
Ogre::MovableObject::getMovableType() const
Ogre::MovableObject::getParentNode() const
Ogre::MovableObject::getParentSceneNode() const
Ogre::MovableObject::isParentTagPoint() const
Ogre::MovableObject::_notifyAttached(Ogre::Node*, bool)
Ogre::MovableObject::isAttached() const
Ogre::MovableObject::detachFromParent()
Ogre::MovableObject::isInScene() const
Ogre::MovableObject::_notifyMoved()
Ogre::MovableObject::_notifyCurrentCamera(Ogre::Camera*)
Ogre::MovableObject::getBoundingBox() const
Ogre::MovableObject::getBoundingRadius() const
Ogre::MovableObject::getWorldBoundingBox(bool) const
Ogre::MovableObject::getWorldBoundingSphere(bool) const
Ogre::MovableObject::_updateRenderQueue(Ogre::RenderQueue*)
Ogre::MovableObject::setVisible(bool)
Ogre::MovableObject::getVisible() const
Ogre::MovableObject::isVisible() const
Ogre::MovableObject::setRenderingDistance(float)
...
I just paste that into the whatever_binding.cpp as a guide, and then cut and paste each line for each function I write.
That'll do, for now.
It makes it much easier to keep track of progress:
When I run out of lines to cut, it means that I am done.

I am porting what I need for whatever I do, and there's a lot missing (of course), but it will get done.
The goal is pure C compliance.
Later on, if some of you use this, you can help porting whatever *you* need..

If you want a flat interface in C++, then take a look at libOkra at Github:
https://github.com/aerique/okra/tree/master/libokra/src
Those files were generated by Aerique's Lisp written tool. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
syd
Gnome
Posts: 362
Joined: Thu May 01, 2008 1:55 am
Location: Paris, France

Re: C interface as core feature

Post by syd »

I wasn't aware of libOkra, that's very useful.

I may sound skeptical, I probably haven't understood, but if the goal is interoperability, then why pure C? what's wrong with "extern C", since it produces a standard C ABI?

edit
okay I got it I think. this is all about early/late binding, am i right? :)
garvek
Gnoblar
Posts: 8
Joined: Sat Nov 29, 2008 11:50 am

Re: C interface as core feature

Post by garvek »

Hello,

Nice project ! Personnaly I was thinking at the same kind of stuff but my way was a litte different, I planned to extract all methods and then create wrappers with an anonymized pointer as 1st argument. Your approach seems to be a lot much cleaner, so I'm looking forward to it. Good work (and good luck) !
tboucher
Gnoblar
Posts: 3
Joined: Wed Oct 21, 2009 5:03 am

Re: C interface as core feature

Post by tboucher »

I had this idea a while ago (partially for OGRE, but generic C++ wrapping as well).

One thing I did look at is using clang to dump it's AST in XML format. This would not only allow you to get the interfaces, but in some cases re-implement certain functions/methods in the target language (C for example) since it is the complete AST. The one issue I ran into was getting enum values out of the AST (I couldn't find them in the dump).

I looked at gcc-xml but it was pretty crappy and unmaintained. SWIG also had it's limitations (largely due to the complexity of OGRE itself).

Since this C API would be mainly for writing bindings to other languages, I'd try to keep a mapping between the C++ classes and the C functions as consistent as possible. For example:

Virtual objects become opaque types:

Code: Select all

namespace Ogre { class Ogre ....};
would become an opaque type like:

Code: Select all

typedef void Ogre_Root;

Code: Select all

bool Ogre::Root::isInitialised(void) const;
would become something like:

Code: Select all

int Ogre_Root_isInitialised(const Ogre_Root*);
Non-virtual types (structs) become plain structs in C

Code: Select all

class Ogre::Vector3 { ... };
would become:

Code: Select all

struct Ogre_Vector3 { Real x, y, z; };
Operator overloads can also have consistent names

Code: Select all

Ogre::Vector3 Ogre::Vector3::operator+(const Ogre::Vector3&) const;
would become:

Code: Select all

Ogre_Vector3 Ogre_Vector3_operator_plus(const Ogre_Vector3*, const Ogre_Vector3*);
In some cases where classes are designed to be abstract, or have any pure virtual methods, a wrapper class would be needed:

Code: Select all

class Foo
{
   virtual void doFoo() = 0;
};
would need a wrapper:

Code: Select all

class Foo_Wrapper : Foo
{
public:
    void doFoo()
    {
        assert(doFoo_cb);
        doFoo_cb();
    }

    void set_doFoo_cb(void (*cb)())
    {
        doFoo_cb = cb;
    }
private:
    void (*doFoo_cb)() = 0;
}
Then the wrapper class can be wrapped for C:

Code: Select all

    void Foo_doFoo(Foo* p) { ((Foo_Wrapper*)p)->doFoo(); }
    void set_doFoo_cb(Foo* p, void (*cb)()) { ((Foo_Wrapper*)p)->set_doFoo_cb(cb); }
Function overloading is another issue, with a few different ways of handling it:

Code: Select all

  int foo(int);
  int foo(int, int);
  int foo(float, int);
could use one of the following methods:

Code: Select all

  int foo_1i(int); int foo_2i(int, int); int foo_1f1i(float, int);

  // or
  int foo_int(int); int foo_int_int(int, int); int foo_float_int(float, int);

  // or
  int foo1(int); int foo2(int, int); int foo3(float, int);
The extra wrapper classes for any class with virtual methods would allow for a certain amount of inheritance to still work.

There are a number of other C++ -> C wrapper tricks, but I think the main thing is keeping consistency with the C++ interfaces. One should be able to look at a C++ method, and know the associated C function and vice-versa.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Code: Select all

Ogre_Vector3 Ogre_Vector3_operator_plus(const Ogre_Vector3*, const Ogre_Vector3*);
Can you really look at this snippet and tell this is a good idea? :P Or better than this:

Code: Select all

void add_v3(Ogre_Vector3* op1, Ogre_Vector3* op2,Ogre_Vector3* result /* may be 0 */);
Also, yours is not a valid C and no tweaks are going to make it so. C and C++ are totally different languages in terms of underlying standards, that makes it harder than that.
Sos Sosowski :)
http://www.sos.gd
Post Reply