首页 > 解决方案 > 为什么在这个简单的 ctypes 示例中出现“访问冲突”错误?

问题描述

我正在探索 Pythonctypes库并遇到访问冲突。我希望有人能告诉我为什么。

这是我的 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

标签: pythonc++cctypes

解决方案


推荐阅读