Note that there are some explanatory texts on larger screens.

plurals
  1. POPython, using ctypes to create C++ class wrapper
    text
    copied!<p>I'm well aware that there is no standard ABI for c++, so this is what I did:</p> <pre><code>//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 </code></pre> <p>And the definition .cpp: (Other class functions' definitions are omitted)</p> <pre><code>//trialDLL.cpp #include "trialDLL.h" MyMathFuncs* __stdcall new_MyMathFuncs(double offset) { return new MyMathFuncs(offset); } void __stdcall del_MyMathFuncs(MyMathFuncs *myMath) { myMath-&gt;~MyMathFuncs(); } double __stdcall MyAdd(MyMathFuncs *myMath, double a, double b) { return myMath-&gt;Add(a, b); } // class functions double MyMathFuncs::Add(double a, double b) { return a+b+ this-&gt;offset; } </code></pre> <p>And I build this into a dll and named it trialDLL3.dll. Then in python, I wrote a module as:</p> <pre><code>#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() </code></pre> <p>After all these, strange things happened. In the IDLE python shell, I did:</p> <pre><code>theMath = MyMath(3.3) #create the instance theMath.FunAdd(3.3, 3.3) #call the function </code></pre> <p>The second line returned None instead of 9.9. Then I tried another way round, putting this line in the shell:</p> <pre><code>theMath.FunMath.MyAdd(theMath.obj, 3.3 ,3.3) </code></pre> <p>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)</p> <pre><code>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) </code></pre> <p>All these lines finally returned 9.9. Aren't these lines identical to the two lines if the trialDLL3.py module is imported?</p> <pre><code>theMath = MyMath(3.3) #create the instance theMath.FunAdd(3.3, 3.3) #call the function </code></pre> <p>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!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload