Почему эта внешняя функция "C" не работает с использованием Python ctypes? - PullRequest
2 голосов
/ 29 февраля 2012

У меня есть следующая функция c ++, которая устанавливает целое число, используя строку.

#include <sstream>
#include <string>
#include <iostream>
using namespace std;

extern "C" {
  int a() {
    int number;
    string value("100");
    std::istringstream strm(value);
    strm >> number;
    if (strm.fail()) {
      cout << "Ouch!" << endl;
    }
    else {
      cout << "Number set to:" << number << endl;
    };
    return (int)strm.bad();
  }
}

int main(int argc, char **argv)
{
  a();
}

Если я скомпилирую это как программу, она будет работать.

$ g++ ./streamtest.cc -o streamtest;./streamtest
Number set to:100

Но если я вызываю ту же функцию из ctypes, она не устанавливает целое число, и "strm" остается в "плохом" состоянии.

$ g++ -shared streamtest.cc  -o libstreamtest.so
$ python -c "import ctypes;a = ctypes.CDLL('libstreamtest.so').a();print 'Got [%s] from a()' %a"
Ouch!
Got [1] from a()

Это меня озадачило. Как я могу заставить эту функцию работать под ctypes?

1 Ответ

1 голос
/ 29 февраля 2012

У меня работает на Windows 7 (x64) с использованием сборки x86.Вы пытались обернуть код с C для использования в качестве модуля с Python?Может быть, это работает для вас ..

C:\Users\niklas\Desktop>g++ -o streamtest.pyd -shared -I"C:\Python27\include" -L"C:\Python27\libs" streamtestmodule.cpp -lpython27


C:\Users\niklas\Desktop>python
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import streamtest
>>> streamtest.a()
Number set to:100
0

#include <Python.h>
#include "streamtest.cpp"

extern "C" {

static PyObject* streamtest_a(PyObject* self) {
    PyObject* re = Py_BuildValue("i", a());
    return re;
}

static PyMethodDef StreamtestMethods[] = {
    {"a", (PyCFunction) streamtest_a, METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL}
};


void initstreamtest(void) {
    PyObject* module = Py_InitModule("streamtest", StreamtestMethods);
    if (module == NULL) {
        cout << "Module initialization failed.";
    }
}

} // extern "C"
...