На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: RaD
  
    > django и lib on c++ в Linux , обычная shared lib на с++ но в linux не прикручиваеться к django
      Проблема заключаеться в создании класса и запуске функций из него из django

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

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

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

      си код dll1.so
      ExpandedWrap disabled
        #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
      ExpandedWrap disabled
        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



      вызов
      ExpandedWrap disabled
        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 так отличается от шел питона. может кто-то подсказать. ?
        Юникод и строка может быть? Какой Python-то?
          ой забыла

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

          python 3.2

          django 1.8


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

          int ff;

          ff=rr;
            краткое описание того как удалось обойти проблему

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

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

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



            си код dll1.so
            ExpandedWrap disabled
              #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
            ExpandedWrap disabled
              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))
            в которую возвращается один и тотже указатель из си приходят разные значения.


            ( прикол сервера -- в чем не знаю - но лечиться так вот .)
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0208 ]   [ 15 queries used ]   [ Generated: 28.03.24, 21:52 GMT ]