I'm exploring the Python ctypes
library and getting an access violation. I was hoping somebody could tell me why.
这是我的C ++代码:
#include <string>
class AComplicatedCPPObj {
int a_;
public:
explicit AComplicatedCPPObj(int a)
: a_(a) {
}
int getA() const {
return a_;
}
void setA(int a) {
a_ = a;
}
};
// And my C wrapper, which is will be exported in the resulting shared library:
#if defined(_WIN64)
extern "C" {
__declspec(dllexport) AComplicatedCPPObj *AComplicatedCPPObj_new(int a) {
return new AComplicatedCPPObj(a);
}
__declspec(dllexport) int AComplicatedCPPObj_getA(AComplicatedCPPObj *aComplicatedCppObj) {
return aComplicatedCppObj->getA();
}
}
#endif
可以使用简单的CMake脚本进行编译和安装:
cmake_minimum_required(VERSION 3.15)
project(ctypesTest)
set(CMAKE_CXX_STANDARD 14)
add_library(ctypesTest SHARED main.cpp)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/INSTALL)
install(TARGETS ctypesTest)
现在在Python中:
import ctypes as c
import os, glob, sys
WORKING_DIRECTORY = os.path.dirname(__file__)
if sys.platform == "linux":
so_path = os.path.join(WORKING_DIRECTORY, "INSTALL/lib/libctypesTest.so")
else:
so_path = os.path.join(WORKING_DIRECTORY, "INSTALL/bin/ctypesTest.dll")
if not os.path.isfile(so_path):
raise FileNotFoundError(so_path)
lib = c.CDLL(so_path)
class AComplicatedCPPObj:
def __init__(self, a):
lib.AComplicatedCPPObj_getA.argtypes = [c.c_void_p]
lib.AComplicatedCPPObj_getA.restype = c.c_int
self.obj = lib.AComplicatedCPPObj_new(a)
def getA(self):
return lib.AComplicatedCPPObj_getA(self.obj)
if __name__ == '__main__':
o = AComplicatedCPPObj(4)
print(o)
print(o.getA())
错误:
C:\Miniconda\envs\py37\python.exe D:/ctypesTest/ctypes_test.py
<__main__.AComplicatedCPPObj object at 0x0000022A7AABD348>
Traceback (most recent call last):
File "D:/ctypesTest/ctypes_test.py", line 32, in <module>
print(o.getA())
File "D:/ctypesTest/ctypes_test.py", line 26, in getA
return lib.AComplicatedCPPObj_getA(self.obj)
OSError: exception: access violation reading 0x000000007A027B80