python AttributeError: Конструктор не определен - Как использовать абстрактный класс swig? - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть файлы API, которые для linux среды. У меня нет доступа к файлу .so, и я не хочу, если возможно, изменять файлы .h, поскольку они могут время от времени обновляться.

ApiProxyWrapper.h

#include <vector>
using namespace std;

class ApiProxyWrapper {
public:
    ApiProxyWrapper(void);
    ~ApiProxyWrapper(void);
    void THEAPI_RegisterApiProxyWrapperReply(ApiProxyWrapperReply* apiProxyWrapperReply);
    int THEAPI_Initialize();
    int THEAPI_Login();
    ......    
private:
};
#endif

ApiProxyWrapperReply.h

#ifndef ApiProxyWrapperReplyH
#define ApiProxyWrapperReplyH
#include <stdio.h>
#include "THEApiProxyDataType.h"
class ApiProxyWrapperReply {
public:
    ApiProxyWrapperReply(void){};
    ~ApiProxyWrapperReply(void){};
    virtual void OnLoginReply(char *user_id, long ret_code,char *ret_msg) = 0;
    virtual void OnConnectedReply(long host_type,long con_status) = 0;
    ......
};
#endif

theapi.i

%module theapi
%{
#include "./include/ApiProxyWrapper.h"
#include "./include/ApiProxyWrapperReply.h"
......
%}
%include "./include/ApiProxyWrapper.h"
%include "./include/ApiProxyWrapperReply.h"
......

команды построения

swig -Wall -c++ -python theapi.i
gcc -fPIC -D__LINUX__ -c theapi_wrap.cxx -I/usr/include/python3.6m
gcc -shared theapi_wrap.o lib/libapiwrapper.so -o _theapi.so

main.py

import theapi
thedll = theapi.ApiProxyWrapper()
thecallback = theapi.ApiProxyWrapperReply() <-- AttributeError
thedll.THEAPI_RegisterApiProxyWrapperReply(thecallback)

AttributeError: нет определен конструктор - класс абстрактный

Я мог бы создать объект ApiProxyWrapper и его методы отвечают. Но я понятия не имею, как использовать THEAPI_RegisterApiProxyWrapperReply в python. Если я не создаю объект ApiProxyWrapperReply, я боюсь, что не будет никакого обратного вызова от API.

TRIAL 01 - жесткие изменения сгенерированного Swig .py

theapi. py

......
class ApiProxyWrapperReply(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, ApiProxyWrapperReply, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, ApiProxyWrapperReply, name)

    def __init__(self, *args, **kwargs):
        #raise AttributeError("No constructor defined - class is abstract")
        pass        
    __repr__ = _swig_repr
    __swig_destroy__ = _spapi.delete_ApiProxyWrapperReply
    __del__ = lambda self: None
    ......
......

main.py

......
thedll.THEAPI_RegisterApiProxyWrapperReply(thecallback) <-- TypeError

TypeError: в методе 'ApiProxyWrapper_THEAPI_RegisterApiProxyWrapperReply', аргумент 2 типа 'ApiProxyWrapperReply *'

TRIAL 02 - использование notabstract

theapi.i

%module theapi
%{
......
%}
%include "./include/ApiProxyWrapper.h"
......
%feature("notabstract") ApiProxyWrapperReply;

main.py то же самое место то же AttributeError

TRIAL 03 - использование директоров

theapi.i

%module(directors="1") theapi
%{
......
%}
%include "./include/ApiProxyWrapper.h"
......
/* C++ std::function<> callback support */
%feature("director") ApiProxyWrapperReply;

main.py то же самое место тот же AttributeError

TRIAL 04 - создать функцию поддержки в C ++

ApiProxy . cpp

#include <cstddef>
#include <string.h>
#include <iostream>
#include <vector>
#include "ApiProxyWrapper.h"
#include "ApiProxyWrapperReply.h"

static ApiProxyWrapper      apiProxyWrapper;
static ApiProxyWrapperReply apiProxyWrapperReply; 

void ApiCreation(){
    apiProxyWrapper.SPAPI_RegisterApiProxyWrapperReply(&apiProxyWrapperReply);
}

команды сборки:

swig -Wall -c++ -python theapi.i
gcc -fPIC -D__LINUX__ -c theapi_wrap.cxx include/ApiProxy.cpp -I/usr/include/python3.6m

include/ApiProxy.cpp:10:29: error: cannot declare variable ‘apiProxyWrapperReply’ to be of abstract type ‘ApiProxyWrapperReply’
 static ApiProxyWrapperReply apiProxyWrapperReply;
                             ^~~~~~~~~~~~~~~~~~~~
In file included from include/ApiProxyWrapper.h:7:0,
                 from include/ApiProxy.cpp:5:
include/ApiProxyWrapperReply.h:8:7: note:   because the following virtual functions are pure within ‘ApiProxyWrapperReply’:

Эта проблема беспокоит меня некоторое время, и я не могу найти решение. Я думаю, что это либо создание указателя класса в python, либо делать какие-то трюки во входном файле, может быть, карты типов? Я не против изменить входной файл, файл python и дополнительные файлы C, кроме файлов .so и .h, предоставленных создателем API.

...