GNU Readline的C++包装程序



我正试图为GNU Readline编写一个c++包装器,以便能够轻松使用自定义补全,但遇到了一个小问题,无法想出解决方案(我对c++还是个新手)。

class ReadLine {
public:
    ReadLine();
    ~ReadLine();
    std::string exec ();
    void enableHistory ();
private:
    std::vector<std::string> keywordList;
    bool history;
private:
    static char** my_completion (const char*, int, int);
    void* xmalloc (int);
    char* generator (const char*, int);
    char* dupstr (std::string);
};

cpp文件:

std::string ReadLine::exec(){
    rl_attempted_completion_function = my_completion;
    std::string buf = "";
    buf = readline("Command>>");
    //enable auto-complete
    rl_bind_key('t',rl_complete);
    if (buf[0]!=0)
        add_history(buf.c_str());
    return buf;
}


char** ReadLine::my_completion (const char* text, int start, int end) {

    char** matches;
    matches = NULL;
    if (start == 0) 
        matches = rl_completion_matches(text, my_generator);
    return matches;

}

我的问题是线路

matches=rl_completion_matches(文本,my_generator)

它显然抛出了一个错误:call to non-static member function without an object argument,但我不想让生成器成为静态的,我找不到它应该使用什么参数,因为我无法访问它内部的类成员(我需要关键字列表来生成关键字)。

你有什么建议?

用一种好的方法解决这个问题并不容易,因为正常的解决方案是通过使用静态包装器函数来解决它,在该函数中,您将指向类的指针作为参数传入。

其他人可能会想出更好的方法,但我认为解决方案是有一个全局变量,它是指向当前ReadLine类实例的指针——这可能是一个堆栈,所以你可以将一个新的堆栈推到它上,然后在完成后弹出它回到旧的堆栈。

在简单的情况下,你会有这样的东西:

ReadLine *currenReadLine = 0;
.... 
std::string ReadLine::exec(){
   ... 
   currentReadLine = this;
}

// declared as static in the class.
char ** ReadLine::my_completion(...)
{
    return currentReadLine->actual_completion(...);
}

以及CCD_ 2的类似解决方案。

最新更新