Почему мой модуль Python C 'hello world' работает правильно во всем, кроме IDLE? - PullRequest
2 голосов
/ 10 марта 2010

Я скомпилировал простой модуль hello world C для Python, и он работает правильно во всем, что я пробовал, кроме IDLE Вот что я печатаю, чтобы проверить это:

>>> import hello
>>> hello.say_hello('Justin')

Я пробовал это с помощью Python из командной строки (я использую Windows), в Eclipse's PyDev и с PieDream, и все они выводят Hello Justin!. Однако в режиме IDLE он ничего не печатает - он просто дает мне подсказку.

Модуль и setup.py, которые я использую, взяты из этой страницы . Я думаю, что проблема с компилятором. Я использую MinGW, который я установил в качестве компилятора distutils в файле .cfg. Я строю модуль из командной строки с:

python setup.py build

и получите

running build
running build_ext
building 'hello' extension
creating build
creating build\temp.win32-2.6
creating build\temp.win32-2.6\Release
C:\MinGW\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python26\include -IC:\Python26\PC -c hellomodule.c -o build\temp.win32-2.6\Release\hellomodule.o
writing build\temp.win32-2.6\Release\hello.def
creating build\lib.win32-2.6
C:\MinGW\bin\gcc.exe -mno-cygwin -shared -s build\temp.win32-2.6\Release\hellomodule.o build\temp.win32-2.6\Release\hello.def -LC:\Python26\libs -LC:Python26\PCbuild -lpython26 -lmsvcr90 -o build\lib.win32-2.6\hello.pyd

Я думаю, что это может быть как-то связано с частью -mno-cygwin, но я не уверен.

Какие-либо идеи или предложения относительно того, почему этот модуль не будет работать в режиме ожидания? Должен ли я использовать другой компилятор?

Ответы [ 2 ]

5 голосов
/ 11 марта 2010

Если вам нужно написать в Python sys.stdout из C-кодированного расширения, вы можете использовать что-то вроде:

void writeout(const char* nullterminated)
{
    PyObject* sysmod = PyImport_ImportModuleNoBlock("sys");
    PyObject* pystdout = PyObject_GetAttrString(sysmod, "stdout");
    PyObject* result = PyObject_CallMethod(pystdout, "write", "s", nullterminated);
    Py_XDECREF(result);
    Py_XDECREF(pystdout);
    Py_XDECREF(sysmod);    
 }

(плюс, предположительно, небольшая проверка ошибок - просто для здравого смысла, на случай, если кто-то совершил что-то сумасшедшее, например del sys.stdout & c; -).

Конечно, если вам нужно несколько записей, может быть более эффективно получить stdout только один раз, хранить его столько раз, сколько необходимо, и дешифровать его только один раз, когда вы закончите «печатать» материал (но это не будет работать правильно в тех случаях, когда ваш вызывающий Python переназначает sys.stdout, в то время как вы сохраняете ссылку на его предыдущую версию: вы будете продолжать печатать в предыдущую версию, точно так же как в Python-кодированном модуле аналогичного поведения) , Этот повторный поиск эквивалентен выполнению sys.stdout.write(somestring) в Python, который также ищет вещи каждый раз - немного медленнее, но "семантически безопаснее" в случае, если ваш вызывающий Python делает "довольно острые" вещи с sys.stdout (как Вы узнали, что делает IDLE ;-). ((На самом деле не все так остро, поэтому вы можете поддержать его должным образом; -)).

5 голосов
/ 10 марта 2010

Похоже, привет пишет прямо в stdout. stdout в Python не обязательно совпадает с C stdout

Обычно вы возвращаете строку в Python, чтобы Python мог напечатать ее в свою собственную stdout

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...