[ https://issues.apache.org/jira/browse/THRIFT-3473?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
YU Chang updated THRIFT-3473: ----------------------------- Description: When a struct/object contains list, the thrift C++ server always return null/undef. Here is my thrift file: {code:title=WordAligner.thrift|borderStyle=solid} namespace cpp WordAligner namespace perl WordAligner struct AlignParamter { 1: string srcLang, 2: string tarLang, 3: optional i32 nBestSize = 1, } struct SentenPair { 1: string srcSenten, 2: string tarSenten, } struct AlignPair { 1: optional string srcWord, 2: optional string tarWord, } struct AlignResult { 1: i32 resultCode, 2: string resultMessage, 3: optional list<list<AlignPair>> nBestAlignPairList, } service WordAlignService { AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair sentenPair), list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: list<SentenPair> sentenPairList) } {code} Here is my C++ code (server): {code:title=WordAlignerServer.cpp|borderStyle=solid} #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TSimpleServer.h> #include <thrift/transport/TServerSocket.h> #include <thrift/transport/TBufferTransports.h> #include "thrift/WordAlignService.h" #include <iostream> #include <cstdlib> 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 ::WordAligner; class WordAlignServiceHandler : virtual public WordAlignServiceIf { public: WordAlignServiceHandler() { } void alignOnePair(AlignResult& _return, const AlignParamter& alignParamter, const SentenPair& sentenPair) { _return.resultCode = 0; _return.resultMessage = "Success"; AlignPair alignPair; alignPair.srcWord = "中国"; alignPair.tarWord = "china"; vector<AlignPair> alignPairVec; alignPairVec.push_back(alignPair); _return.nBestAlignPairList.push_back(alignPairVec); cout << "nBestAlignPairList size: " << _return.nBestAlignPairList.size() << endl; cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord << endl; cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord << endl; } void alignPairList(std::vector<AlignResult> & _return, const AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) { // Your implementation goes here printf("alignPairList\n"); } }; int main(int argc, char **argv) { int port = 9595; shared_ptr<WordAlignServiceHandler> handler(new WordAlignServiceHandler()); shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(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); server.serve(); return 0; } {code} Here is my perl code (client): {code:title=WordAlignerClient.pl|borderStyle=solid} #!/usr/bin/perl use v5.12; use warnings; use autodie; use utf8; use Data::Dumper; use lib 'gen-perl-wordalign'; use WordAligner::WordAlignService; use WordAligner::Constants; use WordAligner::Types; use Thrift; use Thrift::BinaryProtocol; use Thrift::Socket; use Thrift::BufferedTransport; my $socket = new Thrift::Socket('localhost', 9595); my $transport = new Thrift::BufferedTransport($socket, 1024, 1024); my $protocol = new Thrift::BinaryProtocol($transport); my $client = new WordAligner::WordAlignServiceClient($protocol); my $align_param = new WordAligner::AlignParamter; $align_param->srcLang('zh-CN'); $align_param->tarLang('en'); my $src_senten = "中国 政府 高度 重视 经济 发展 。"; my $tar_senten = "china 's government attached great importance to economic development ."; my $senten_pair = new WordAligner::SentenPair; $senten_pair->srcSenten($src_senten); $senten_pair->tarSenten($tar_senten); eval { $transport->open(); my $result = $client->alignOnePair($align_param, $senten_pair); say Dumper($result); $transport->close(); }; say $@ if $@; {code} {code:title=C++ server output|borderStyle=solid} nBestAlignPairList size: 1 src word: 中国 tar word: china {code} {code:title=perl client output|borderStyle=solid} $VAR1 = bless( { 'resultMessage' => 'Success', 'resultCode' => 0, 'nBestAlignPairList' => undef }, 'WordAligner::AlignResult' ); {code} For solving this problem, I have already tried to: 1) return just one level list, not list of list; 2) using C++ client to test; 3) upgrade thrift version from 0.9.1 to 0.9.3; But nothing help, the return list is still empty. was: When a struct/object contains list, the thrift C++ server always return null/undef. Here is my thrift file: {code:title=WordAligner.thrift|borderStyle=solid} namespace cpp WordAligner namespace perl WordAligner struct AlignParamter { 1: string srcLang, 2: string tarLang, 3: optional i32 nBestSize = 1, } struct SentenPair { 1: string srcSenten, 2: string tarSenten, } struct AlignPair { 1: optional string srcWord, 2: optional string tarWord, } struct AlignResult { 1: i32 resultCode, 2: string resultMessage, 3: optional list<list<AlignPair>> nBestAlignPairList, } service WordAlignService { AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair sentenPair), list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: list<SentenPair> sentenPairList) } {code} Here is my C++ code (server): {code:title=WordAlignerServer.cpp|borderStyle=solid} #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TSimpleServer.h> #include <thrift/transport/TServerSocket.h> #include <thrift/transport/TBufferTransports.h> #include "thrift/WordAlignService.h" #include <iostream> #include <cstdlib> 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 ::WordAligner; class WordAlignServiceHandler : virtual public WordAlignServiceIf { public: WordAlignServiceHandler() { } void alignOnePair(AlignResult& _return, const AlignParamter& alignParamter, const SentenPair& sentenPair) { _return.resultCode = 0; _return.resultMessage = "Success"; AlignPair alignPair; alignPair.srcWord = "中国"; alignPair.tarWord = "china"; vector<AlignPair> alignPairVec; alignPairVec.push_back(alignPair); _return.nBestAlignPairList.push_back(alignPairVec); cout << "nBestAlignPairList size: " << _return.nBestAlignPairList.size() << endl; cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord << endl; cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord << endl; } void alignPairList(std::vector<AlignResult> & _return, const AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) { // Your implementation goes here printf("alignPairList\n"); } }; int main(int argc, char **argv) { int port = 9595; shared_ptr<WordAlignServiceHandler> handler(new WordAlignServiceHandler()); shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(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); server.serve(); return 0; } {code} Here is my perl code (client): {code:title=WordAlignerClient.pl|borderStyle=solid} #!/usr/bin/perl use v5.12; use warnings; use autodie; use utf8; use Data::Dumper; use lib 'gen-perl-wordalign'; use WordAligner::WordAlignService; use WordAligner::Constants; use WordAligner::Types; use Thrift; use Thrift::BinaryProtocol; use Thrift::Socket; use Thrift::BufferedTransport; my $socket = new Thrift::Socket('localhost', 9595); my $transport = new Thrift::BufferedTransport($socket, 1024, 1024); my $protocol = new Thrift::BinaryProtocol($transport); my $client = new WordAligner::WordAlignServiceClient($protocol); my $align_param = new WordAligner::AlignParamter; $align_param->srcLang('zh-CN'); $align_param->tarLang('en'); my $src_senten = "中国 政府 高度 重视 经济 发展 。"; my $tar_senten = "china 's government attached great importance to economic development ."; my $senten_pair = new WordAligner::SentenPair; $senten_pair->srcSenten($src_senten); $senten_pair->tarSenten($tar_senten); eval { $transport->open(); my $result = $client->alignOnePair($align_param, $senten_pair); say Dumper($result); $transport->close(); }; say $@ if $@; {code} C++ server output: {code:title=C++ server output|borderStyle=solid} nBestAlignPairList size: 1 src word: 中国 tar word: china {code} perl client output: {code:title=perl client output|borderStyle=solid} $VAR1 = bless( { 'resultMessage' => 'Success', 'resultCode' => 0, 'nBestAlignPairList' => undef }, 'WordAligner::AlignResult' ); {code} For solving this problem, I have already tried to: 1) return just one level list, not list of list; 2) using C++ client to test; 3) upgrade thrift version from 0.9.1 to 0.9.3; But nothing help, the return list is still empty. > C++ server cannot correctly return a struct/object contains list > ---------------------------------------------------------------- > > Key: THRIFT-3473 > URL: https://issues.apache.org/jira/browse/THRIFT-3473 > Project: Thrift > Issue Type: Bug > Components: C++ - Library > Affects Versions: 0.9.3 > Environment: CentOS 7, GCC 4.8.3, Perl 5.16 > Reporter: YU Chang > > When a struct/object contains list, the thrift C++ server always return > null/undef. > Here is my thrift file: > {code:title=WordAligner.thrift|borderStyle=solid} > namespace cpp WordAligner > namespace perl WordAligner > struct AlignParamter { > 1: string srcLang, > 2: string tarLang, > 3: optional i32 nBestSize = 1, > } > struct SentenPair { > 1: string srcSenten, > 2: string tarSenten, > } > struct AlignPair { > 1: optional string srcWord, > 2: optional string tarWord, > } > struct AlignResult { > 1: i32 resultCode, > 2: string resultMessage, > 3: optional list<list<AlignPair>> nBestAlignPairList, > } > service WordAlignService { > AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair > sentenPair), > list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: > list<SentenPair> sentenPairList) > } > {code} > Here is my C++ code (server): > {code:title=WordAlignerServer.cpp|borderStyle=solid} > #include <thrift/protocol/TBinaryProtocol.h> > #include <thrift/server/TSimpleServer.h> > #include <thrift/transport/TServerSocket.h> > #include <thrift/transport/TBufferTransports.h> > #include "thrift/WordAlignService.h" > #include <iostream> > #include <cstdlib> > 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 ::WordAligner; > class WordAlignServiceHandler : virtual public WordAlignServiceIf { > public: > WordAlignServiceHandler() { > } > void alignOnePair(AlignResult& _return, const AlignParamter& > alignParamter, const SentenPair& sentenPair) { > _return.resultCode = 0; > _return.resultMessage = "Success"; > AlignPair alignPair; > alignPair.srcWord = "中国"; > alignPair.tarWord = "china"; > vector<AlignPair> alignPairVec; > alignPairVec.push_back(alignPair); > _return.nBestAlignPairList.push_back(alignPairVec); > cout << "nBestAlignPairList size: " << > _return.nBestAlignPairList.size() << endl; > cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord > << endl; > cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord > << endl; > } > void alignPairList(std::vector<AlignResult> & _return, const > AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) > { > // Your implementation goes here > printf("alignPairList\n"); > } > }; > int main(int argc, char **argv) { > int port = 9595; > shared_ptr<WordAlignServiceHandler> handler(new > WordAlignServiceHandler()); > shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(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); > server.serve(); > return 0; > } > {code} > Here is my perl code (client): > {code:title=WordAlignerClient.pl|borderStyle=solid} > #!/usr/bin/perl > use v5.12; > use warnings; > use autodie; > use utf8; > use Data::Dumper; > use lib 'gen-perl-wordalign'; > use WordAligner::WordAlignService; > use WordAligner::Constants; > use WordAligner::Types; > use Thrift; > use Thrift::BinaryProtocol; > use Thrift::Socket; > use Thrift::BufferedTransport; > my $socket = new Thrift::Socket('localhost', 9595); > my $transport = new Thrift::BufferedTransport($socket, 1024, 1024); > my $protocol = new Thrift::BinaryProtocol($transport); > my $client = new WordAligner::WordAlignServiceClient($protocol); > my $align_param = new WordAligner::AlignParamter; > $align_param->srcLang('zh-CN'); > $align_param->tarLang('en'); > my $src_senten = "中国 政府 高度 重视 经济 发展 。"; > my $tar_senten = "china 's government attached great importance to economic > development ."; > my $senten_pair = new WordAligner::SentenPair; > $senten_pair->srcSenten($src_senten); > $senten_pair->tarSenten($tar_senten); > eval { > $transport->open(); > my $result = $client->alignOnePair($align_param, $senten_pair); > say Dumper($result); > $transport->close(); > }; > say $@ if $@; > {code} > {code:title=C++ server output|borderStyle=solid} > nBestAlignPairList size: 1 > src word: 中国 > tar word: china > {code} > {code:title=perl client output|borderStyle=solid} > $VAR1 = bless( { > 'resultMessage' => 'Success', > 'resultCode' => 0, > 'nBestAlignPairList' => undef > }, 'WordAligner::AlignResult' ); > {code} > For solving this problem, I have already tried to: > 1) return just one level list, not list of list; > 2) using C++ client to test; > 3) upgrade thrift version from 0.9.1 to 0.9.3; > But nothing help, the return list is still empty. -- This message was sent by Atlassian JIRA (v6.3.4#6332)