2013-07-10 2 views
4

я сделал простой бережливость файл так:Apache Бережливость: Возвращение списка/контейнер

thrifttest.thrift

namespace cpp thrifttest 
namespace d thrifttest 
namespace java thrifttest 
namespace php thrifttest 
namespace perl thrifttest 

service Test { 

    list<i64> ping(); 

} 

и в оболочке побежал "бережливость --gen CPP thrifttest.thrift"

Однако, когда я смотрел на GEN-CPP/Test_server.skeleton.cpp он сделал список i64 параметр, а не тип возвращаемого значения:

Test_server.skeleton.cpp (выдержка)

void ping(std::vector<int64_t> & _return) { 
    // Your implementation goes here 
    printf("ping\n"); 
} 

и в моей server.cpp программе, после того, как я делаю функцию пинг(), которая возвращает "СТД :: вектор &", компилятор жалуется, что

error: cannot allocate an object of abstract type ‘TestHandler’ server.cpp:30:7: note: because the following virtual functions are pure within ‘TestHandler’:

это полный код server.cpp server.cpp

#include <thrift/concurrency/ThreadManager.h> 
#include <thrift/concurrency/PosixThreadFactory.h> 
#include <thrift/protocol/TBinaryProtocol.h> 
#include <thrift/server/TSimpleServer.h> 
#include <thrift/server/TThreadPoolServer.h> 
#include <thrift/server/TThreadedServer.h> 
#include <thrift/transport/TServerSocket.h> 
#include <thrift/transport/TTransportUtils.h> 

#include <iostream> 
#include <stdexcept> 
#include <sstream> 

#include "gen-cpp/Test.h" 

using namespace std; 
using namespace apache::thrift; 
using namespace apache::thrift::protocol; 
using namespace apache::thrift::transport; 
using namespace apache::thrift::server; 

using boost::shared_ptr; 

using namespace thrifttest; 

using namespace boost; 

unsigned long giant[100]; 

class TestHandler : virtual public TestIf { 
public: 
    TestHandler() { 
     for (int i = 0; i < 100; i++) { 
      giant[i] = -1; 
     } 
    } 


    std::vector<int64_t> & ping() { 
     return (std::vector<int64_t> &)giant; 
    } 

    void ping(std::vector<int64_t> & bla) {} 
}; 

int main(int argc, char **argv) { 

    shared_ptr<TestHandler> handler(new TestHandler()); 
    shared_ptr<TProcessor> processor(new TestProcessor(handler)); 
    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); 
    shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); 
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); 

    TSimpleServer server(processor, 
         serverTransport, 
         transportFactory, 
         protocolFactory); 

    printf("Starting the server...\n"); 
    server.serve(); 
    printf("done.\n"); 
    return 0; 
} 

ответ

9

Я случайно наткнулся на статью (StackOverflow: Handling Apache Thrift List Map Return Types in C), в которой обсуждалась эта точная проблема (хотя в моем случае ответ не работал). Оказывается, бережливость использует синтаксис pass-by-reference, хотя "Thrift uses a pass by value model" - Gupta. Так вот пример:

.thrift файл

service Test { 

    list<string> ping(); 
} 

стороне сервера

void ping(std::vector<string> & _return) { 
    _return.push_back("hello"); //initialize the vector _return with values "hello","world" 
    _return.push_back("world"); 
} 

стороне клиента

std::vector<string> result;  //create vector "result" for storing the values 
client.ping(result); 
printf("%s %s!\n", result[0].c_str(), result[1].c_str()); //c_str() turns the vector string into a C-style string 

выхода клиента (после запуска сервера)

hello world!

и спасибо бережливости за отсутствие документов, у меня был взрыв! # 4hoursgoogling & crying

+1

+1 для 'и спасибо вам за недостаток документации, у меня был взрыв! # 4hoursgoogling & crying'. В той же фазе в курсе. : '( – TheRookierLearner

+1

если вам что-нибудь понадобится, я могу попытаться помочь :) – woojoo666

+2

Во-первых, с открытым исходным кодом живет и от вас. Это оба пути. Плач не улучшит ситуацию и не поможет тем, кто имеет одни и те же вопросы.Далее имеется * документация (и да, она далека от совершенства), как учебники и другие примеры кода, такие как книги и публикации и сообщения в блогах, все из которых связаны несколько раз с другими вопросами SO. И последнее, что не менее важно, вы можете спросить в любое время здесь, в SO, в списке рассылки Thrift и канале #thrift Freenode. Может быть, этого недостаточно, и вы знаете лучше? Отлично, вы более чем рады, мы принимаем патчи и вклады! – JensG

1

Помимо вашего вопроса, есть несколько недостатков с возвратом класса контейнера непосредственно.

Вместо этого я бы обернул контейнер в struct и вернул его. Таким образом, вы можете добавлять любые поля позже без необходимости использования нового метода службы. Более того, сам контейнер можно опустить, если это становится необходимым - вы не можете вернуть контейнер NULL по техническим причинам с помощью Thrift.

Смежные вопросы