I'm well aware that there is no standard ABI for c++, so this is what I did:
我很清楚c++没有标准的ABI,所以我这样做了:
//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)
和定义。cpp:(省略其他类函数的定义)
//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:
我将它构建到一个dll中并命名为trialDLL3.dll。然后在python中,我编写了一个模块:
#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:
在这一切之后,奇怪的事情发生了。在空闲的python shell中,我这样做了:
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:
第二行返回None,而不是9.9。然后我尝试了另一种方法,把这条线放在壳里:
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)
这条线返回给我的是9。9,这并不令人惊讶,但与最后一个结果相比,结果为0。这两行不应该是一样的吗?我决定用python shell显式地运行所有这些行,看看会出现什么问题,写:(不包括导入)
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?
所有这些行最终返回9.9。如果是trialDLL3,这两条线不是完全相同的吗?py模块是进口的吗?
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!
如果它们是相同的,为什么两行类版本返回None,而显式方式返回9.9?提前谢谢!
1 个解决方案
#1
5
Everything works fine... but you forgot to pass along the return value of the C function in the method MyMath.FunAdd!
一切都好…但是您忘记了在MyMath.FunAdd方法中传递C函数的返回值!
def FunAdd(self, a, b):
return self.FunMath.MyAdd(self.obj, a, b)
^^^^^^
#1
5
Everything works fine... but you forgot to pass along the return value of the C function in the method MyMath.FunAdd!
一切都好…但是您忘记了在MyMath.FunAdd方法中传递C函数的返回值!
def FunAdd(self, a, b):
return self.FunMath.MyAdd(self.obj, a, b)
^^^^^^