Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Python > django и lib on c++ в Linux


Автор: def 10.12.17, 15:21
Проблема заключаеться в создании класса и запуске функций из него из django

Причем если запускать из командной строки просто питоном - то все равботает -

а django не видит переменных класса.
(swing и прочее не очень подходит так как нужна библиотека so с возможнотьсю подключения и к питону и к другой программе на с++ и к чемуто еще. )

- краткий пример

си код dll1.so
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    #include <stdio.h>
    #include <vector>
     
    using namespace std;
    class Foo{
        
        public:
      int ff;
            char* bar(int rr){
                std::cout << "Hello" << std::endl;
              
                ff=rr;
                char* tt = new char[4];
                 tt[0]='e';
                 tt[1]='t';
                 tt[2]='b';
                 tt[3]='r';
     
                return tt ;
            }
    };
     
    extern "C" {
        Foo* Foo_new(){ return new Foo(); }
        char* Foo_bar(Foo* foo,int rr){return foo->bar(rr);}
    }




питоновская оболочка. getC1.py
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    import ctypes
    lib = ctypes.CDLL('./dll1.so',mode=ctypes.RTLD_GLOBAL)
    #lib = cdll.LoadLibrary('./polls/libdll.so')
     
    class Foo(object):
        def __init__(self):
            self.obj = lib.Foo_new()
     
        def barw(self,tt):
            ty=lib.Foo_bar(self.obj,tt)
            print(" %s " % ty)
            return ty



вызов
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    import ctypes
    from  getC1 import Foo
     
    f=Foo()
    rr=f.barw(555)
    print(" %s " % rr)


Если в вставлять этот вызов в django то вешаеться все на строке ff=rr;
ибо ff не существует

если заменить строку self.obj = lib.Foo_new()
на self.obj = hex(lib.Foo_new())

то тогда работает за исключение переданного char - здесь указатель опять сбоит
и сделать чтото типо ctypes.cast(ty ,ctypes.c_char_p) нельзя вобще сваливаеться с ошибкой сегментации - если опять так сделать hex то уже видит строку


lib.Foo_new.restypes = ctypes.POINTER(ctypes.c_void_p)
и прочии не помогает - если их прописываешь все также теряет чать указателя - нужен hex


Чем django так отличается от шел питона. может кто-то подсказать. ?

Автор: piksel 10.12.17, 17:22
Юникод и строка может быть? Какой Python-то?

Автор: def 11.12.17, 06:59
ой забыла

linux debian разновидности

python 3.2

django 1.8


строка и юникод точно пока не причем так как без hex падает на int переменной

int ff;

ff=rr;

Автор: def 14.12.17, 13:42
краткое описание того как удалось обойти проблему

сначала подробность .
при вызове
f=Foo()
происходит
self.obj = lib.Foo_new()
которое возвращает вовсе не тот указатель который создает конструктор - а обрубленный и сдвинутый - даже если поставить hex - он совпадает периодически и на удачу с реальным. - причина в сервере на котором развернута джанга ( увы не доступен для анализа )

но обойти удалось следующим образом -

меняем dll на следующий вариант



си код dll1.so
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    #include <stdio.h>
    #include <vector>
     
    using namespace std;
    class Foo{
        
        public:
      int ff;
            int bar(int rr , char** resStr ){
                std::cout << "Hello" << std::endl;
              
                ff=rr;
                char* tt = new char[4];
                 tt[0]='e';
                 tt[1]='t';
                 tt[2]='b';
                 tt[3]='r';
     
                *resStr =tt;
              
              return 1;
            }
    };
     
    extern "C" {
        Foo* Foo_new( Foo** fooRes ){
             Foo*  fooCreate = new Foo();
             *fooRes =fooCreate;
             return fooCreate /*хотя это уже  просто для сравнения  указателя*/; }
        int Foo_bar(Foo* foo,int rr , char** resStr ){   return foo->bar(rr,resStr );}
    }




и также класс питона меняем на


питоновская оболочка. getC1.py
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    import ctypes
    lib = ctypes.CDLL('./dll1.so',mode=ctypes.RTLD_GLOBAL)
     
     
    class Foo(object):
        def __init__(self):
            self.objReal  =ctypes.c_void_p()
            self.obj = lib.Foo_new(ctypes.byref(self.objReal))
     
        def barw(self,tt):
            resstr=ctypes.c_char_p()
            ty=lib.Foo_bar(self.objReal  ,tt ,ctypes.byref(resstr) )
            print(" %s " % resstr)
            return resstr




и все работает ...

при этом строка
self.obj = lib.Foo_new(ctypes.byref(self.objReal))
в которую возвращается один и тотже указатель из си приходят разные значения.


( прикол сервера -- в чем не знаю - но лечиться так вот .)

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)