#c #python #c #python-c-api
#c #python #c #python-c-api
Вопрос:
Редактирование выполнено: я оборачиваю пользовательскую библиотеку DLL python с целью в конечном итоге удалить пользовательский код и использовать новейший python вместо древней версии, которая используется сейчас. Одна из функций инициализирует расширение python и вызывает
PyObject* _PyObject_New(PyTypeObject *type)
В моей оболочке происходит сбой объекта (c), созданного этим вызовом PyErr_Print()
(да, я его тоже завернул).
Я хотел бы поэкспериментировать с заменой вызовов Repr или Str на что-нибудь по своему выбору, чтобы посмотреть, виноваты ли они. Кроме того, я не могу использовать капсулы, потому что предполагается, что объекты доступны даже в коде python.
По запросу: реальная проблема возникает везде, где вызывается один из двух собственных указателей c. Я взял исходный код python 2.7.1, открыл в VS 2003 (проект находится на PC / VS7.1), открыл pythonrun.c
там и добавил заглушки функций тройки в конце:
static CHAR gameHome[MAX_PATH 1] = { 0 };
__declspec (dllexport) void Py_SetGameInterface(){
//Set the path here
unsigned long nChars;
nChars = GetModuleFileName(NULL, gameHome, MAX_PATH);
if(nChars <= 0){
printf("Failed getting the exe pathn");
return;
}
for( ; nChars > 0; nChars--){
//think windows accepts both
if(gameHome[nChars]=='\' || gameHome[nChars]=='/'){
break;
}
}
if(nChars == 0){
printf("Failed getting the python pathn");
return;
}
strcpy(amp;gameHome[nChars 1],"Bin\python");
Py_SetPythonHome(gameHome);
}
/* this was deprecated in python 2.3 but vampire needs it */
#undef _PyObject_Del
__declspec (dllexport) void _PyObject_Del(PyObject *op)
{
PyObject_FREE(op);
}
//original returns the number of chars output
//if you give it a char* youll receive what was written but that
//looks like a accident of the stack
__declspec (dllexport) int Py_FlushConsoleOutput(){
return 0;
}
__declspec (dllexport) int PyRun_ConsoleString(char * str, int typeOfExpression, PyObject * globals, PyObject * locals){
PyObject* ret = NULL;
printf("Console String: %s, size %dn", str, strlen(str));
if(PyErr_Occurred() != NULL){
printf("WTF ERRORn%s", PyString_AsString(PyObject_Str(PyErr_Occurred())));
PyErr_Clear();
}
//trying to run dir(cvar) crashes here
ret = PyRun_String(str, typeOfExpression, globals, locals);
if(ret != NULL){
Py_DECREF(ret);
}
//ret crashes with non null ret
return 0;
}
#undef PyRun_String
PyAPI_FUNC(PyObject *)
PyRun_String(char *str, int s, PyObject *g, PyObject *l)
{
PyObject* r;
if(PyErr_Occurred() != NULL){
printf("WTF ERRORn%s", PyString_AsString(PyObject_Str(PyErr_Occurred())));
PyErr_Clear();
}
r = PyRun_StringFlags(str, s, g, l, NULL);
if(r != NULL amp;amp; PyBool_Check(r)){
//newer python defined a bool value but bloodlines is
//not accepting it somehow (though bool is a subclass of int)
if(r == Py_True)
return PyInt_FromLong(1L);
else
return PyInt_FromLong(0L);
}
return r;
}
Создайте решение, но удалили подпроекты python, которые не работают (они не нужны)
поместите этот файл bash в каталог Game / Bin (где находится библиотека DLL python)
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/python27.dll ./vampire_python21.dll
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/unicodedata.pyd ./python/unicodedata.pyd
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/_ctypes.pyd ./python/_ctypes.pyd
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/select.pyd ./python/select.pyd
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/winsound.pyd ./python/winsound.pyd
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/python.exe ./python/python.exe
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/pythonw.exe ./python/pythonw.exe
cp -f /home/paulo/OS Images/shared/Python-2.7.1/PC/VS7.1/w9xpopen.exe ./python/w9xpopen.exe
rm -R ./python/Lib
cp -R /home/paulo/OS Images/shared/Python-2.7.1/Lib ./python/Lib
find ../ -name '*.pyc' -delete
export PYTHONVERBOSE=1; wine ../vampire.exe -console 1
скомпилирован и запущен. Игра открывается с консоли, и если вы введете dir(cvar)
, она вылетит после создания AST во время запуска / печати кода (извините, wine не понимает символы VS debug). Любопытно, что другой собственный указатель «dir (ccmd)» не аварийно завершает работу, но может содержать некоторые подсказки о том, что не так с другим:
[]
Console String: __dict__, size 8
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name '__dict__' is not defined
Console String: __members__, size 11
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name '__members__' is not defined
Console String: __methods__, size 11
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name '__methods__' is not defined
Console String: __class__, size 9
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name '__class__' is not defined
Обратите внимание, что он вылетает РАНЬШЕ (РЕДАКТИРОВАТЬ: на самом деле, он каким-то образом вызывается снова. Исключения в python C api? Необходимо провести расследование. ПРАВКА2: на самом деле это происходит только в команде «dir (ccmd)», а не в команде «dir(cvar)», которая сразу же завершает работу) возврат и что эта функция зависит от консоли. Вполне могут быть другие изменения, о которых я не знаю.
«print ccmd», «str (ccmd)» или «repr (ccmd)» на консоли выдает :
<cvar object at 0x0245E4A8>
и «print cvar», «str (cvar)» или «repr (cvar)» выдает
<cvar object at 0x0245E4A0>
Также обратите внимание, что я не знаю, что такое возврат ConsoleString
функции, но я знаю, что она тестируется на 0 (NULL) в сборке возврата к ветви a if.
РЕДАКТИРОВАТЬ: ОК, нашли точку сбоя, применив debbuger к прикрепленному при сбое: это строка 3963 typeobject.c в исходном коде python 2.7.1,
if (base amp;amp; base->tp_dict == NULL)
Значение Base не равно null, однако доступ к этому словарю приводит к сбою интерпретатора. Должен ли я отправлять отчет об ошибке?
Комментарии:
1. Я ничего из этого не могу понять. Я не думаю, что вы получите хороший ответ, если не объясните, что вы делаете более подробно.
2. @i30817 Вы пишете на C или Си? Это два очень разных языка, в названиях которых случайно присутствует «C».
3. c. Я просто беру исходный код python и добавляю 3 метода, добавленных troika. API тот же, просто у меня есть доступ к обоим, поскольку я использую компилятор c .
4. опубликуйте внесенные вами изменения. мы все еще не знаем, что вы сделали и почему. возможно, это просто проблема в вашем коде.
5. Хорошо, но это будет непонятно, если у вас нет игры и вы не можете скомпилировать код и запустить его тоже.