+1  A: 

In your internal functions, you can only return zvals, not arbitrary C++ objects. In your case, you must encapsulate the Category object either in a resource or in an object (like you did for the Graph object). Either way, you cannot automatically use the C++ object's methods and properties. You must then provide functions or methods (again, like you did for the Graph object) that then should call the underlying native methods and convert their results into zvals.

edit: OK, I assume you've already declare the Category class as a PHP class, its class entry table is in ce_category and you have this type:

struct category_object {
    zend_object std;
    Category *categ;
};

then:

PHP_METHOD(Graph, getCategory)
{
    graph_object *obj = (graph_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    struct category_object *co;

    //You ought to check whether obj is NULL and maybe throw an exception or call zend_error...
    if (object_init_ex(return_value, ce_category) != SUCCESS) {
        //error handling
    }

    co = (struct category_object *) zend_object_store_get_object(return_value TSRMLS_CC);
    assert (co != NULL); //should not happen; object was just created
    co->categ = retrieve_category_from_graph(obj->graph);

    /* IMPORTANT NOTE: if the Category object is held by the Graph object
     * (that is, it is freed when the Graph object is freed), you should either:
     * - Copy the Category object, so that it is independent.
     * - Increment the refcount of the PHP Graph object with
     *   zend_objects_store_add_ref(_by_handle). In that case, you should also store the
     *   handle of the PHP Graph object so that you can decrease the refcount when the
     *   PHP Category object is destroyed. Alternatively, you can store an IS_OBJECT
     *   zval and indirectly manipulate the object refcount through construction/destruction
     *   of the zval */
}
Artefacto