1

As I'm still new to this, I'm facing some problems, here's my C++ code:

#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);

}

And the Python code:

import ctypes

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

jj = MyDll.Add(1,2)

I get an error when I run the above Python code:

OSError: exception: access violation reading 0x000000000000000A

I want to pass the data, without converting it, from Python to C++, then convert it inside C++.

2 Answers 2

4

Use either an extension or ctypes; you're not supposed to call your extension through ctypes. The point of extensions is to be able to create modules that look native to people using them from Python. ctypes serves to call C code that was written completely oblivious of Python.

Sign up to request clarification or add additional context in comments.

Comments

3

There are a few things that are wrong with your code. First and foremost, the proper include is:

#include <Python.h>

Note the capital P. You're probably on Windows, but this wouldn't work on Linux without the capital P.

Also, I don't see the point of the *pSelf pointer in your function declaration, you should get rid of it:

PyObject *Add(PyObject *pArgs)

Now, your main problem is this:

MyDll.Add(1,2)

...does not call MyDll.Add with a tuple. It calls it with two integer arguments, 1 and 2. If you want to pass a tuple, you'd do:

MyDll.Add((1,2))

However, Python's ctypes won't know what to do with this (it normally accepts integer arguments), so you'll need to tell it that Add actually wants a tuple, and returns a Python object:

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))

6 Comments

wow,you are awesome :D it worked like a charm :) just need more explain about : why remove *pSelf as I've seen it on all online functions and didn't understand MyCFunc part ("Add",MyDll)
@MohamedSakrAboYoucuf: Because Add is not actually a member of a class instance, but a static function. self is only passed automatically by the interpreter as the first argument to methods, not functions.
one last thing,is there a way to extract object method inside c++?
@netcoder is the statement "return NULL;" correct? Shouldn't it return Py_None or something?
@Czarek what i think is (int in python != int in c++),which means for example (5 in python != 5 in c++) due to infrastructure of each language but 0 in all languages is a 0 (its binary code is a simple 0 :D)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.