Stefan Behnel | 8 Feb 16:33
Picon
Favicon
Gravatar

[Cython] C++ method overloading?

Hi,

I'm trying to implement the PyBindGen micro-benchmarks in cython-devel by
wrapping this source file:

http://bazaar.launchpad.net/~gjc/pybindgen/trunk/annotate/735/benchmarks/testapi.cc
http://bazaar.launchpad.net/~gjc/pybindgen/trunk/annotate/735/benchmarks/testapi.h

(I know, few Cython users would wrap code at that granularity, but that's
about the limit of what PyBindGen can handle.)

The API is basically this (I attached the two wrapper source files I wrote):

------------------
cdef extern from "testapi.h":
    void func1()
    double func2(double x, double y, double z)

    cdef cppclass Multiplier:
        Multiplier()
        Multiplier(double factor)
        void SetFactor()
        void SetFactor(double f)
        double GetFactor()
        double Multiply(double value)

    double call_virtual_from_cpp (Multiplier *obj, double value)
------------------

Cython parses this just fine - however, when I try to call the SetFactor
method in Cython code, I get this:

Error converting Pyrex file to C:
------------------------------------------------------------
...
    def __dealloc__(self):
        del self.multiplier

    def SetFactor(self, f=None):
        if f is None:
            self.multiplier.SetFactor()
                                    ^
------------------------------------------------------------
.../pytestapi.pyx:18:37: Call with wrong number of arguments (expected 1,
got 0)

The exact error depends on the order in which I declare the two methods. It
seems that the last declaration wins. And Cython also doesn't complain
about the constructor call right two methods above, so that seems to have
worked.

Is this supposed to work for regular C++ methods?

Stefan

cimport testapi

cdef class Multiplier:
    cdef testapi.Multiplier* multiplier

    def __cinit__(self, factor=None):
        if factor is None:
            self.multiplier = testapi.Multiplier()
        else:
            self.multiplier = testapi.Multiplier(factor)

    def __dealloc__(self):
        del self.multiplier

    def SetFactor(self, f=None):
        if f is None:
            self.multiplier.SetFactor()
        else:
            self.multiplier.SetFactor(f)

    def GetFactor(self):
        return self.multiplier.GetFactor()

    def Multiply(self, double value):
        return self.multiplier.Multiply(value)

def func1():
    testapi.func1()

def func2(double x, double y, double z):
    return testapi.func2(x, y, z)

def call_virtual_from_cpp(testapi.Multiplier *obj, double value):
    return testapi.call_virtual_from_cpp(obj, value)
Attachment (testapi.cc): text/x-c++src, 710 bytes
Attachment (testapi.h): text/x-chdr, 542 bytes

cdef extern from "testapi.h":
    void func1()
    double func2(double x, double y, double z)

    cdef cppclass Multiplier:
        Multiplier()
        Multiplier(double factor)
        void SetFactor()
        void SetFactor(double f)
        double GetFactor()
        double Multiply(double value)

    double call_virtual_from_cpp (Multiplier *obj, double value)

Gmane