Python, using ctypes to create C++ class wrapper
Question: I'm well aware that there is no standard ABI for c++, so this is what I did:

    
    
    //trialDLL.h
    #ifndef TRIALDLL_H_
    #define TRIALDLL_H_
    
    class MyMathFuncs
    {
    private:
        double offset;
    
    public:
        MyMathFuncs(double offset);
    
        ~MyMathFuncs();
    
        double Add(double a, double b);
    
        double Multiply(double a, double b);
    
        double getOffset();
    };
    
    #ifdef __cplusplus
    extern "C"{
    #endif
    
    #ifdef TRIALDLL_EXPORT
    #define TRIALDLL_API __declspec(dllexport)
    #else
    #define TRIALDLL_API __declspec(dllimport)
    #endif
    
        TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset);
    
        TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath);
    
        TRIALDLL_API double __stdcall MyAdd(MyMathFuncs* myMath, double a, double b);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

And the definition .cpp: (Other class functions' definitions are omitted)

    
    
    //trialDLL.cpp
    #include "trialDLL.h"
    
    MyMathFuncs* __stdcall new_MyMathFuncs(double offset)
    {
    return new MyMathFuncs(offset);
    }
    
    
    void __stdcall del_MyMathFuncs(MyMathFuncs *myMath)
    {
        myMath->~MyMathFuncs();
    }
    
    
    double __stdcall MyAdd(MyMathFuncs *myMath, double a, double b)
    {
    return myMath->Add(a, b);
    }
    
    // class functions
    double MyMathFuncs::Add(double a, double b)
    {
    return a+b+ this->offset;
    }
    

And I build this into a dll and named it trialDLL3.dll. Then in python, I
wrote a module as:

    
    
    #trialDLL3.py
    import ctypes
    from ctypes import WinDLL
    
    class MyMath(object):
        def __init__(self, offset):
            self.FunMath = WinDLL('trialDLL3.dll')
            self.FunMath.new_MyMathFuncs.argtypes = [ctypes.c_double]
            self.FunMath.new_MyMathFuncs.restype = ctypes.c_void_p
    
            self.FunMath.MyAdd.argtypes = [ctypes.c_void_p, \
                                           ctypes.c_double, ctypes.c_double]
            self.FunMath.MyAdd.restype = ctypes.c_double
    
            self.obj = self.FunMath.new_MyMathFuncs(offset)
    
        def FunAdd(self, a, b):
            self.FunMath.MyAdd(self.obj, a, b)
    
        def delete(): 
            self.FunMath.del_MyMathFuncs()
    

After all these, strange things happened. In the IDLE python shell, I did:

    
    
    theMath = MyMath(3.3)        #create the instance
    theMath.FunAdd(3.3, 3.3)     #call the function
    

The second line returned None instead of 9.9. Then I tried another way round,
putting this line in the shell:

    
    
    theMath.FunMath.MyAdd(theMath.obj, 3.3 ,3.3)
    

And this line returns me an unsurprising 9.9, but surprising when compared to
the last result None. Shouldn't these two lines identical? And I decided to
run all those lines explicitly in python shell and see what can go wrong,
writing: (excluding the imports)

    
    
    loadedDLL = WinDLL('trialDLL3.dll')
    loadedDLL.new_MyMathFuncs.argtypes = [ctypes.c_double]
    loadedDLL.new_MyMathFuncs.restype = ctypes.c_void_p
    loadedDLL.MyAdd.argtypes = [ctypes.c_void_p, \
                                        ctypes.c_double, ctypes.c_double]
    loadedDLL.MyAdd.restype = ctypes.c_double
    obj = loadedDLL.new_MyMathFuncs(3.3)
    FunMath.MyAdd(obj, 3.3, 3.3)
    

All these lines finally returned 9.9. Aren't these lines identical to the two
lines if the trialDLL3.py module is imported?

    
    
    theMath = MyMath(3.3)        #create the instance
    theMath.FunAdd(3.3, 3.3)     #call the function
    

If they are the same deal, why the two line class version returns None and the
explicit way return expected 9.9? Thanks in advance!


Answer: Everything works fine... but you forgot to pass along the return value of the
C function in the method MyMath.FunAdd!

    
    
    def FunAdd(self, a, b):
        return self.FunMath.MyAdd(self.obj, a, b)
        ^^^^^^
    

