使用ctypes在Python中调用C++

1 投票
2 回答
1015 浏览
提问于 2025-04-17 17:20

我还是个新手,所以遇到了一些问题。以下是我的C++代码:

#include <python.h>

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT PyObject *Add(PyObject *pSelf, PyObject *pArgs)
{
    int s,d;
    if(!PyArg_ParseTuple(pArgs, "ii" , &s, &d))
    {
        PyErr_SetString(PyExc_TypeError,
                "Add() invalid parameter");
        return NULL;
    }

    return Py_BuildValue("i", s + d);

}

还有我的Python代码:

import ctypes

MyDll = ctypes.cdll.LoadLibrary(r"PyToCppTest.dll")

jj = MyDll.Add(1,2)

当我运行上面的Python代码时,出现了一个错误:

OSError: exception: access violation reading 0x000000000000000A

我想把数据从Python传到C++,而不进行转换,然后在C++里面再进行转换。

2 个回答

4

可以使用扩展或者 ctypes;但是不应该通过 ctypes 来调用你的扩展。扩展的目的是为了让使用 Python 的人能够创建看起来很自然的模块。而 ctypes 是用来调用那些完全不考虑 Python 的 C 代码的。

3

你的代码有几个问题。首先,正确的引入方式是:

#include <Python.h>

注意大写的 P。你可能是在Windows上,但在Linux上没有大写的P是无法工作的。

另外,我觉得你在函数声明中使用的 *pSelf 指针没有必要,你应该把它去掉:

PyObject *Add(PyObject *pArgs)

现在,你的主要问题是这个:

MyDll.Add(1,2)

...没有用元组来调用 MyDll.Add。它是用两个整数参数 12 来调用的。如果你想传一个元组,你应该这样做:

MyDll.Add((1,2))

不过,Python的ctypes不知道该如何处理这个(它通常只接受整数参数),所以你需要告诉它 Add 实际上是想要一个元组,并且返回一个Python对象:

import ctypes

MyDll = ctypes.cdll.LoadLibrary("PyToCppTest.dll")
MyCFunc = ctypes.PYFUNCTYPE(
    ctypes.py_object,     # return val: a python object
    ctypes.py_object      # argument 1: a tuple
)
MyFunc = MyCFunc(('Add', MyDll))

jj = MyFunc((1,2))

撰写回答