Есть ли способ вызвать код c / c из python без изменения кода c / c ?

#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. Хорошо, но это будет непонятно, если у вас нет игры и вы не можете скомпилировать код и запустить его тоже.