Kaynağa Gözat

add some carmaker service program.

yuchuli 2 yıl önce
ebeveyn
işleme
661b55a309

+ 2 - 4
src/include/proto3/carmaker.proto

@@ -43,7 +43,6 @@ message workReply {
   string strOutputName = 4;
   string strcmd = 5;
   bytes data_Input = 6;
-  bytes data_Output = 7;
 }
 
 message cvtReq
@@ -52,12 +51,11 @@ message cvtReq
   string strOutputName = 2;
   string strcmd = 3;
   bytes data_Input = 4;
-  bytes data_Output = 5;
-  int32 mCvtTimeLimms = 6; //default 30s
+  int32 mCvtTimeLimms = 5; //default 30s
 }
 
 message cvtReply {
-  int32 mnRes = 1; //0 Work OK  -1 Convert Fail  -2 No CARMAKER CONVERT SERVICE
+  int32 mnRes = 1; //1 Work OK  -1 Convert Fail  -2 No CARMAKER CONVERT SERVICE -3 Server can't Connect.
   bytes xdata = 2;  
 
 }

+ 15 - 0
src/test/carmakerexecwork/carmakerexecwork.cpp

@@ -0,0 +1,15 @@
+#include "carmakerexecwork.h"
+
+
+//Carmakerexecwork::Carmakerexecwork()
+//{
+//}
+
+
+
+int ExecCarmakerWork(int64_t workid,std::string strInputName, std::string strOutputName, std::string strcmd,
+                     std::shared_ptr<char> pinput_ptr,int ninputsize,
+                     std::shared_ptr<char> & poutput_ptr,int noutputsize)
+{
+    return 0;
+}

+ 27 - 0
src/test/carmakerexecwork/carmakerexecwork.h

@@ -0,0 +1,27 @@
+#ifndef CARMAKEREXECWORK_H
+#define CARMAKEREXECWORK_H
+
+#include <QtCore/qglobal.h>
+
+#include <memory>
+#include <string>
+
+#if defined(CARMAKEREXECWORK_LIBRARY)
+#  define CARMAKEREXECWORKSHARED_EXPORT Q_DECL_EXPORT
+#else
+#  define CARMAKEREXECWORKSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+
+int ExecCarmakerWork(int64_t workid,std::string strInputName, std::string strOutputName, std::string strcmd,
+                     std::shared_ptr<char> pinput_ptr,int ninputsize,
+                     std::shared_ptr<char> & poutput_ptr,int noutputsize);
+
+//class CARMAKEREXECWORKSHARED_EXPORT Carmakerexecwork
+//{
+
+//public:
+//    Carmakerexecwork();
+//};
+
+#endif // CARMAKEREXECWORK_H

+ 36 - 0
src/test/carmakerexecwork/carmakerexecwork.pro

@@ -0,0 +1,36 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2022-11-17T14:39:57
+#
+#-------------------------------------------------
+
+QT       -= gui
+
+TARGET = carmakerexecwork
+TEMPLATE = lib
+
+DEFINES += CARMAKEREXECWORK_LIBRARY
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+CONFIG += plugin
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        carmakerexecwork.cpp
+
+HEADERS += \
+        carmakerexecwork.h
+
+unix {
+    target.path = /usr/lib
+    INSTALLS += target
+}

+ 96 - 0
src/test/carmakerservice/carmakerimpl.cpp

@@ -1,14 +1,110 @@
 #include "carmakerimpl.h"
 
+#include <memory>
+#include <string>
+#include <vector>
+#include <mutex>
+
 
 Status CarmakerImpl::convertreq(ServerContext* context, const iv::ipg::cvtReq* request,
                 iv::ipg::cvtReply* reply)
 {
+    (void)context;
+    int inputsize = static_cast<int>(request->data_input().size()) ;
+    std::shared_ptr<char> pinput_ptr = std::shared_ptr<char>(new char[inputsize]);
+    memcpy(pinput_ptr.get(),request->data_input().data(),static_cast<size_t>(inputsize) );
+    int64_t nWorkID =  mWT.AddTask(request->strinputname(),request->stroutputname(),request->strcmd(),pinput_ptr,inputsize);
+    int waitms = 30000;
+    if(request->mcvttimelimms() > 300)
+    {
+        waitms = request->mcvttimelimms();
+    }
+    bool bComplete = false;
+    int nres = -2; //Default no carmaker service
+    int64_t nStartWait = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
+    std::shared_ptr<char> pout_ptr = nullptr;
+    int nOutSize = 0;
+    while(bComplete == false)
+    {
+        int64_t nNow = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
+        int nWaitleft = static_cast<int>(nNow - nStartWait);
+        nWaitleft = waitms - nWaitleft;
+        if(nWaitleft<=0)
+        {
+            break;
+        }
+
+        std::unique_lock<std::mutex> lk(mmutex_cv);
+        if(mcv.wait_for(lk, std::chrono::milliseconds(nWaitleft)) == std::cv_status::timeout)
+        {
+            lk.unlock();
+            continue;
+        }
+        else
+        {
+            lk.unlock();
+            continue;
+        }
+        if(mWT.InqureTaskComplete(nWorkID))
+        {
+            mWT.GetTaskRes(nWorkID,nres,pout_ptr,nOutSize);
+            break;
+        }
 
+    }
+
+    reply->set_mnres(nres);
+    if(nres == 1)
+    {
+        if(pout_ptr != nullptr)
+        {
+            reply->set_xdata(pout_ptr.get(),static_cast<size_t>(nOutSize) );
+        }
+        else
+        {
+            std::cout<<" Task res is 1, but not have data. Please Check."<<std::endl;
+        }
+    }
+    return Status::OK;
 }
 
 Status CarmakerImpl::convertwork(ServerContext* context, const iv::ipg::workReq * request,
                    iv::ipg::workReply* reply)
 {
 
+    (void)context;
+    if(request->mnres() != 0)
+    {
+        int ndatasize = 0;
+        std::shared_ptr<char> pout_ptr = nullptr;
+        if(request->mnres() == 1)
+        {
+           ndatasize = static_cast<int>(request->xdata().size()) ;
+           pout_ptr = std::shared_ptr<char>(new char[ndatasize]);
+           memcpy(pout_ptr.get(),request->xdata().data(),static_cast<size_t>(ndatasize) );
+        }
+        mWT.SetTaskRes(request->workid(),request->mnres(),pout_ptr,ndatasize);
+        mcv.notify_all();
+    }
+
+    int64_t nWorkID;
+    std::string strInputName;
+    std::string strOUtputName;
+    std::string strcmd;
+    std::shared_ptr<char> pInput_ptr = nullptr;
+    int nInputSize;
+    if(mWT.ReqTask(strInputName,strOUtputName,strcmd,pInput_ptr,nInputSize,nWorkID) == 1)
+    {
+        reply->set_mnres(1);
+        reply->set_workid(nWorkID);
+        reply->set_strinputname(strInputName);
+        reply->set_stroutputname(strOUtputName);
+        reply->set_strcmd(strcmd);
+        reply->set_data_input(pInput_ptr.get(),static_cast<size_t>(nInputSize) );
+    }
+    else
+    {
+        reply->set_mnres(0);
+    }
+    return Status::OK;
 }

+ 12 - 0
src/test/carmakerservice/carmakerimpl.h

@@ -4,6 +4,8 @@
 #include <iostream>
 #include <memory>
 #include <string>
+#include <condition_variable>
+#include <mutex>
 
 #include <grpcpp/grpcpp.h>
 #include <grpcpp/health_check_service_interface.h>
@@ -19,12 +21,22 @@ using grpc::ServerContext;
 using grpc::Status;
 
 
+#include "worktask.h"
+
+
 class CarmakerImpl   final: public iv::ipg::Carmaker::Service
 {
+public:
     Status convertreq(ServerContext* context, const iv::ipg::cvtReq* request,
                     iv::ipg::cvtReply* reply) override;
     Status convertwork(ServerContext* context, const iv::ipg::workReq * request,
                        iv::ipg::workReply* reply) override;
+
+private:
+    WorkTask mWT;
+
+    std::condition_variable mcv;
+    std::mutex mmutex_cv;
 };
 
 #endif // CARMAKERIMPL_H

+ 95 - 0
src/test/carmakerservice/main.cpp

@@ -4,7 +4,91 @@
 
 #include "signal.h"
 
+#include "carmakerimpl.h"
 
+static char gstrport[255];
+
+
+#include <getopt.h>
+
+void print_useage()
+{
+    std::cout<<" -p --port $port : port . eq.  -p 50051"<<std::endl;
+    std::cout<<" -h --help print help"<<std::endl;
+}
+
+int  GetOptLong(int argc, char *argv[]) {
+    int nRtn = 0;
+    int opt; // getopt_long() 的返回值
+//    int digit_optind = 0; // 设置短参数类型及是否需要参数
+
+    // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
+    // 第几个元素的描述,即是long_opts的下标值
+    int option_index = 0;
+    // 设置短参数类型及是否需要参数
+    const char *optstring = "m:r:x:y:o:p:s:h";
+
+
+    static struct option long_options[] = {
+        {"port", required_argument, NULL, 'p'},
+        {"help",  no_argument,       NULL, 'h'},
+ //       {"optarg", optional_argument, NULL, 'o'},
+        {0, 0, 0, 0}  // 添加 {0, 0, 0, 0} 是为了防止输入空值
+    };
+
+    while ( (opt = getopt_long(argc,
+                               argv,
+                               optstring,
+                               long_options,
+                               &option_index)) != -1) {
+        switch(opt)
+        {
+
+        case 'p':
+            strncpy(gstrport,optarg,255);
+            break;
+        case 'h':
+            print_useage();
+            nRtn = 1; //because use -h
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    return nRtn;
+}
+
+
+
+void RunServer() {
+  std::string server_address("0.0.0.0:");
+  server_address = server_address.append(gstrport);
+  CarmakerImpl service;
+
+  grpc::EnableDefaultHealthCheckService(true);
+//  grpc::reflection::InitProtoReflectionServerBuilderPlugin();
+  ServerBuilder builder;
+  // Listen on the given address without any authentication mechanism.
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+
+  builder.SetMaxReceiveMessageSize(300000000);
+ // builder.SetMaxMessageSize(100000000);
+
+
+//  builder.SetMaxSendMessageSize(100000000);
+  // Register "service" as the instance through which we'll communicate with
+  // clients. In this case it corresponds to an *synchronous* service.
+  builder.RegisterService(&service);
+  // Finally assemble the server.
+  std::unique_ptr<Server> server(builder.BuildAndStart());
+  std::cout << "Server listening on " << server_address << std::endl;
+
+  // Wait for the server to shutdown. Note that some other thread must be
+  // responsible for shutting down the server for this call to ever return.
+  server->Wait();
+}
 
 void signal_handler(int sig)
 {
@@ -21,5 +105,16 @@ int main(int argc, char *argv[])
 
     signal(SIGINT,signal_handler);
 
+    snprintf(gstrport,255,"50091");
+
+    int nRtn = GetOptLong(argc,argv);
+    if(nRtn == 1)  //show help,so exit.
+    {
+        return 0;
+    }
+
+
+    RunServer();
+
     return a.exec();
 }

+ 11 - 5
src/test/carmakerservice/worktask.cpp

@@ -65,7 +65,7 @@ int WorkTask::ReqTask(std::string & strInputName,std::string & strOutputName,std
     mMutex.unlock();
 }
 
-void WorkTask::SetTaskRes(int nID,int ncvtRes,std::shared_ptr<char> xdata_Output,int nOutputSize)
+void WorkTask::SetTaskRes(int64_t nID,int ncvtRes,std::shared_ptr<char> xdata_Output,int nOutputSize)
 {
     mMutex.lock();
     unsigned int i;
@@ -75,8 +75,11 @@ void WorkTask::SetTaskRes(int nID,int ncvtRes,std::shared_ptr<char> xdata_Output
         if(mvecterTask[i].mnTaskID == nID)
         {
             mvecterTask[i].mnCvtRes = ncvtRes;
-            mvecterTask[i].mdata_Output = xdata_Output;
-            mvecterTask[i].mnOutputSize = nOutputSize;
+            if(ncvtRes == 1)
+            {
+                mvecterTask[i].mdata_Output = xdata_Output;
+                mvecterTask[i].mnOutputSize = nOutputSize;
+            }
             mvecterTask[i].mbComplete = true;
             break;
         }
@@ -84,8 +87,9 @@ void WorkTask::SetTaskRes(int nID,int ncvtRes,std::shared_ptr<char> xdata_Output
     mMutex.unlock();
 }
 
-int WorkTask::GetTaskRes(int nID,int & ncvtRes,std::shared_ptr<char> & xdata_Output, int & nOutputSize)
+int WorkTask::GetTaskRes(int64_t nID,int & ncvtRes,std::shared_ptr<char> & xdata_Output, int & nOutputSize)
 {
+    int nrtn = 0;
     mMutex.lock();
     unsigned int i;
     unsigned int nsize = static_cast<unsigned int>(mvecterTask.size()) ;
@@ -97,13 +101,15 @@ int WorkTask::GetTaskRes(int nID,int & ncvtRes,std::shared_ptr<char> & xdata_Out
             xdata_Output = mvecterTask[i].mdata_Output;
             nOutputSize = mvecterTask[i].mnOutputSize;
             mvecterTask.erase(mvecterTask.begin()+i);
+            nrtn = 1;
             break;
         }
     }
     mMutex.unlock();
+    return nrtn;
 }
 
-bool WorkTask::InqureTaskComplete(int nID)
+bool WorkTask::InqureTaskComplete(int64_t nID)
 {
     bool bComplete = false;
     mMutex.lock();

+ 3 - 3
src/test/carmakerservice/worktask.h

@@ -36,9 +36,9 @@ public:
     int64_t AddTask(std::string strInputName,std::string strOutputName,std::string strcmd,std::shared_ptr<char> xdata_Input,int nInputSize);
     void DeleteTask(int mnID);
     int ReqTask(std::string & strInputName,std::string & strOutputName,std::string & strcmd,std::shared_ptr<char> & xdata_Input,int & nInputSize,int64_t &nID); //if 1 a task . if 0 no task
-    void SetTaskRes(int nID,int ncvtRes,std::shared_ptr<char> xdata_Output,int nOutputSize);
-    int GetTaskRes(int nID,int & ncvtRes,std::shared_ptr<char> & xdata_Output, int & nOutputSize);
-    bool InqureTaskComplete(int nID);
+    void SetTaskRes(int64_t nID,int ncvtRes,std::shared_ptr<char> xdata_Output,int nOutputSize);
+    int GetTaskRes(int64_t nID,int & ncvtRes,std::shared_ptr<char> & xdata_Output, int & nOutputSize);
+    bool InqureTaskComplete(int64_t nID);
 
 
 private:

+ 73 - 0
src/test/carmakerwork/.gitignore

@@ -0,0 +1,73 @@
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+.directory
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+

+ 27 - 0
src/test/carmakerwork/carmakerexecwork.h

@@ -0,0 +1,27 @@
+#ifndef CARMAKEREXECWORK_H
+#define CARMAKEREXECWORK_H
+
+#include <QtCore/qglobal.h>
+
+#include <memory>
+#include <string>
+
+#if defined(CARMAKEREXECWORK_LIBRARY)
+#  define CARMAKEREXECWORKSHARED_EXPORT Q_DECL_EXPORT
+#else
+#  define CARMAKEREXECWORKSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+
+int ExecCarmakerWork(int64_t workid,std::string strInputName, std::string strOutputName, std::string strcmd,
+                     std::shared_ptr<char> pinput_ptr,int ninputsize,
+                     std::shared_ptr<char> & poutput_ptr,int noutputsize);
+
+//class CARMAKEREXECWORKSHARED_EXPORT Carmakerexecwork
+//{
+
+//public:
+//    Carmakerexecwork();
+//};
+
+#endif // CARMAKEREXECWORK_H

+ 113 - 0
src/test/carmakerwork/carmakerwork.cpp

@@ -0,0 +1,113 @@
+#include "carmakerwork.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+carmakerwork::carmakerwork(std::string strserver)
+{
+    mstrserver = strserver;
+    mbRun = true;
+    mpthread = new std::thread(&carmakerwork::threadwork,this);
+}
+
+carmakerwork::~carmakerwork()
+{
+    mbRun = false;
+    mpthread->join();
+}
+
+
+void carmakerwork::threadwork()
+{
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+                mstrserver, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::ipg::Carmaker::Stub> stub_ = iv::ipg::Carmaker::NewStub(channel);
+
+
+
+
+    gpr_timespec timespec;
+    timespec.tv_sec = 10;//设置阻塞时间为2秒
+    timespec.tv_nsec = 0;
+    timespec.clock_type = GPR_TIMESPAN;
+
+    int64_t interval = 100;
+
+    int64_t lastreq = 0;
+
+    int nRes = 0;
+    std::shared_ptr<char> pout_ptr = nullptr;
+    int64_t nWorkID;
+    int nOutSize;
+
+    while(mbRun)
+    {
+
+        if(nRes == 0)
+        {
+            int64_t nnow = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
+            int64_t diff = static_cast<int64_t>(abs(nnow - lastreq)) ;
+            if(diff<interval)
+            {
+                std::this_thread::sleep_for(std::chrono::milliseconds(interval-diff));
+            }
+        }
+        iv::ipg::workReq request;
+
+        // Container for the data we expect from the server.
+        iv::ipg::workReply reply;
+
+        request.set_mnres(nRes);
+        if(nRes == 1)
+        {
+            if(pout_ptr != nullptr)
+            {
+               request.set_workid(nWorkID);
+               request.set_xdata(pout_ptr.get(),static_cast<size_t>(nOutSize));
+            }
+            else
+            {
+                std::cout<<" carmaker work. nres is 1, but no data. please check."<<std::endl;
+            }
+        }
+
+        nRes = 0; //Set res to Default;
+
+        ClientContext context ;
+        context.set_deadline(timespec);
+
+        lastreq = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
+
+        Status status = stub_->convertwork(&context, request, &reply);
+        if (status.ok()) {
+
+            if(reply.mnres() == 1)
+            {
+                nWorkID = reply.workid();
+                std::shared_ptr<char> pinput_ptr = nullptr;
+                int ninputsize = static_cast<int>(reply.data_input().size()) ;
+                nRes = ExecCarmakerWork(nWorkID,reply.strinputname(),reply.stroutputname(),reply.strcmd(),
+                                        pinput_ptr,ninputsize,pout_ptr,nOutSize);
+            }
+            if(reply.mnres() == 0)
+            {
+                std::cout<<" no work."<<std::endl;
+                nRes = 0;
+            }
+        } else {
+            std::cout << status.error_code() << ": " << status.error_message()
+                      << std::endl;
+            std::cout<<"RPC failed"<<std::endl;
+
+
+        }
+
+    }
+
+}

+ 35 - 0
src/test/carmakerwork/carmakerwork.h

@@ -0,0 +1,35 @@
+#ifndef CARMAKERWORK_H
+#define CARMAKERWORK_H
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <thread>
+
+#include <grpcpp/grpcpp.h>
+
+#include "carmaker.grpc.pb.h"
+
+#include "carmakerexecwork.h"
+
+
+class carmakerwork
+{
+public:
+    carmakerwork(std::string strserver = "127.0.0.1:50091");
+    ~carmakerwork();
+
+private:
+    std::string mstrserver;
+
+    std::thread * mpthread;
+    bool mbRun = true;
+
+
+private:
+    void threadwork();
+
+
+};
+
+#endif // CARMAKERWORK_H

+ 42 - 0
src/test/carmakerwork/carmakerwork.pro

@@ -0,0 +1,42 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += main.cpp \
+    ../carmakerservice/carmaker.grpc.pb.cc \
+    ../../include/msgtype/carmaker.pb.cc \
+    carmakerwork.cpp
+
+INCLUDEPATH += $$PWD/../../../src/include/msgtype
+INCLUDEPATH += $$PWD/../carmakerservice
+
+DEFINES += TESTC
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+!include(../../../include/ivgrpc.pri ) {
+    error( "Couldn't find the ivgrpc.pri file!" )
+}
+
+HEADERS += \
+    ../carmakerservice/carmaker.grpc.pb.h \
+    ../../include/msgtype/carmaker.pb.h \
+    carmakerwork.h \
+    carmakerexecwork.h
+
+
+LIBS += -L$$PWD -lcarmakerexecwork

+ 35 - 0
src/test/carmakerwork/main.cpp

@@ -0,0 +1,35 @@
+#include <QCoreApplication>
+
+#include "carmakerwork.h"
+
+#include <QFile>
+
+carmakerwork * gpwork;
+
+
+std::string GetServerstr()
+{
+    std::string strserverstr = "111.33.136.149:50091";
+    QFile xFile;
+    xFile.setFileName("carmakerwork.txt");
+    if(xFile.open(QIODevice::ReadOnly))
+    {
+        char str[256];
+        xFile.readLine(str,256);
+        std::cout<<" open file. server : "<<str<<std::endl;
+        strserverstr = str;
+        xFile.close();
+    }
+    return  strserverstr;
+}
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    std::string strserverstr = GetServerstr();
+
+    gpwork = new carmakerwork(strserverstr);
+
+    return a.exec();
+}

+ 73 - 0
src/test/xodr2rd5_grpc/.gitignore

@@ -0,0 +1,73 @@
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+.directory
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+

+ 65 - 0
src/test/xodr2rd5_grpc/carmakercvt.cpp

@@ -0,0 +1,65 @@
+#include "carmakercvt.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+carmakercvt::carmakercvt(std::string strserver )
+{
+    mstrserver = strserver;
+}
+
+int carmakercvt::GetRes(std::string strinputname,std::string stroutputname,std::string strcmd,std::shared_ptr<char> pinput_ptr,int ninputsize,
+                        std::shared_ptr<char> & pout_ptr,int & noutputsize)
+{
+    int nrtn = -2;
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+                mstrserver, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::ipg::Carmaker::Stub> stub_ = iv::ipg::Carmaker::NewStub(channel);
+
+
+    iv::ipg::cvtReq request;
+
+    // Container for the data we expect from the server.
+    iv::ipg::cvtReply reply;
+
+    gpr_timespec timespec;
+    timespec.tv_sec = 60;//设置阻塞时间为2秒
+    timespec.tv_nsec = 0;
+    timespec.clock_type = GPR_TIMESPAN;
+
+    request.set_strinputname(strinputname);
+    request.set_stroutputname(stroutputname);
+    request.set_strcmd(strcmd);
+    request.set_data_input(pinput_ptr.get(),static_cast<size_t>(ninputsize) );
+
+
+    ClientContext context ;
+    context.set_deadline(timespec);
+
+    Status status = stub_->convertreq(&context, request, &reply);
+    if (status.ok()) {
+        nrtn = reply.mnres();
+        if(nrtn == 1)
+        {
+
+        }
+
+    } else {
+      std::cout << status.error_code() << ": " << status.error_message()
+                << std::endl;
+      std::cout<<"RPC failed"<<std::endl;
+      nrtn = -3;
+
+    }
+
+    return  nrtn;
+
+
+
+}

+ 24 - 0
src/test/xodr2rd5_grpc/carmakercvt.h

@@ -0,0 +1,24 @@
+#ifndef CARMAKERCVT_H
+#define CARMAKERCVT_H
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#include "carmaker.grpc.pb.h"
+
+class carmakercvt
+{
+public:
+    carmakercvt(std::string strserver = "127.0.0.1:50091");
+
+    int GetRes(std::string strinputname,std::string stroutputname,std::string strcmd,std::shared_ptr<char> pinput_ptr,int ninputsize,
+               std::shared_ptr<char> & pout_ptr,int & noutputsize);
+
+private:
+    std::string mstrserver;
+};
+
+#endif // CARMAKERCVT_H

+ 241 - 0
src/test/xodr2rd5_grpc/main.cpp

@@ -0,0 +1,241 @@
+#include <QCoreApplication>
+
+#include <QFile>
+
+#include <iostream>
+#include <memory>
+
+#include <getopt.h>
+
+#include "carmakercvt.h"
+
+static char gstr_inputpath[256];
+static char gstr_outputpath[256];
+
+void print_useage()
+{
+    std::cout<<" -i --input $xodrfile : set  input file path. eq.  -i d:/lk.xodr"<<std::endl;
+    std::cout<<" -o --output $outputfile : set output file. eq.  -o d:/test.rd5"<<std::endl;
+    std::cout<<" -h --help print help"<<std::endl;
+}
+
+int  GetOptLong(int argc, char *argv[]) {
+    int nRtn = 0;
+    int opt; // getopt_long() 的返回值
+    int digit_optind = 0; // 设置短参数类型及是否需要参数
+    (void)digit_optind;
+
+    // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
+    // 第几个元素的描述,即是long_opts的下标值
+    int option_index = 0;
+    // 设置短参数类型及是否需要参数
+    const char *optstring = "i:o:h";
+
+    // 设置长参数类型及其简写,比如 --reqarg <==>-r
+    /*
+    struct option {
+             const char * name;  // 参数的名称
+             int has_arg; // 是否带参数值,有三种:no_argument, required_argument,optional_argument
+             int * flag; // 为空时,函数直接将 val 的数值从getopt_long的返回值返回出去,
+                     // 当非空时,val的值会被赋到 flag 指向的整型数中,而函数返回值为0
+             int val; // 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值
+        };
+    其中:
+        no_argument(即0),表明这个长参数不带参数(即不带数值,如:--name)
+            required_argument(即1),表明这个长参数必须带参数(即必须带数值,如:--name Bob)
+            optional_argument(即2),表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
+     */
+    static struct option long_options[] = {
+        {"input", required_argument, NULL, 'i'},
+        {"output", required_argument, NULL, 'o'},
+        {"help",  no_argument,       NULL, 'h'},
+ //       {"optarg", optional_argument, NULL, 'o'},
+        {0, 0, 0, 0}  // 添加 {0, 0, 0, 0} 是为了防止输入空值
+    };
+
+    while ( (opt = getopt_long(argc,
+                               argv,
+                               optstring,
+                               long_options,
+                               &option_index)) != -1) {
+//        printf("opt = %c\n", opt); // 命令参数,亦即 -a -b -n -r
+//        printf("optarg = %s\n", optarg); // 参数内容
+//        printf("optind = %d\n", optind); // 下一个被处理的下标值
+//        printf("argv[optind - 1] = %s\n",  argv[optind - 1]); // 参数内容
+//        printf("option_index = %d\n", option_index);  // 当前打印参数的下标值
+//        printf("\n");
+        switch(opt)
+        {
+        case 'i':
+            strncpy(gstr_inputpath,optarg,255);
+            break;
+        case 'o':
+            strncpy(gstr_outputpath,optarg,255);
+            break;
+        case 'h':
+            print_useage();
+            nRtn = 1; //because use -h
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    return nRtn;
+}
+
+
+
+std::string GetFileName(char * strpath)
+{
+    int npos = -1;
+    int nsize = static_cast<int>(strnlen(strpath,256));
+    int i;
+    for(i=(nsize-2);i>=0;i--)
+    {
+        if((strpath[i] == '/')||(strpath[i] == '\\'))
+        {
+            npos = i+1;
+            break;
+        }
+    }
+
+    std::string strrtn;
+    if(npos  == -1)
+    {
+        strrtn = strpath;
+    }
+    else
+    {
+        char strname[256];
+        strncpy(strname,strpath+npos,256);
+        strrtn = strname;
+    }
+    return strrtn;
+}
+
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    int nRtn = GetOptLong(argc,argv);
+    if(nRtn == 1)  //show help,so exit.
+    {
+        return 0;
+    }
+
+
+#ifdef TESTC
+    snprintf(gstr_inputpath,255,"/home/yuchuli/demodata/lk.xodr");
+    snprintf(gstr_outputpath,255,"D:/lk.rd5");
+#endif
+
+    if(strncmp(gstr_inputpath , "",255) == 0)
+    {
+        std::cout<<"Please use -i set input file path."<<std::endl;
+        print_useage();
+        return 0;
+    }
+
+    char strout[1000];
+    snprintf(strout,1000,"Input File Path: %s",gstr_inputpath);
+    std::cout<<strout<<std::endl;
+
+    if(strncmp(gstr_outputpath , "",255) == 0)
+    {
+        std::cout<<"Please use -o set output file path."<<std::endl;
+        print_useage();
+        return 0;
+    }
+
+    snprintf(strout,1000,"Output File Path: %s",gstr_outputpath);
+    std::cout<<strout<<std::endl;
+
+    std::string strinputname = GetFileName(gstr_inputpath);
+    std::string stroutputname = GetFileName(gstr_outputpath);
+
+    std::cout<<"input name: "<<strinputname<<std::endl;
+
+    std::string strcmd = "xodr2rd5.exe ";
+    strcmd = strcmd + "-i "+strinputname + " -o "+stroutputname;
+    std::cout<<"cmd: "<<strcmd<<std::endl;
+
+    std::shared_ptr<char> pstr_ptr = nullptr;
+    int ninputsize = 0;
+    QFile xFile;
+    xFile.setFileName(gstr_inputpath);
+    if(xFile.open(QIODevice::ReadOnly))
+    {
+        QByteArray ba= xFile.readAll();
+        ninputsize = ba.size();
+        if(ninputsize > 0)
+        {
+            pstr_ptr = std::shared_ptr<char>(new char[ninputsize]);
+            memcpy(pstr_ptr.get(),ba.data(),static_cast<size_t>(ninputsize));
+        }
+        xFile.close();
+    }
+    else
+    {
+        std::cout<<"FATAL Errror. Can't Open input File. Please Check Input File."<<std::endl;
+        return -1;
+    }
+
+    if(ninputsize == 0)
+    {
+        std::cout<<"FATAL Error. Input File is empty."<<std::endl;
+        return  -2;
+    }
+
+    std::shared_ptr<char> pout_ptr;
+    int noutputsize = 0;
+    int nres;
+
+    carmakercvt * pcvt = new carmakercvt();
+    nres = pcvt->GetRes(strinputname,stroutputname,strcmd,pstr_ptr,ninputsize,pout_ptr,noutputsize);
+
+    if(nres != 1)
+    {
+        std::cout<<" GetRes Fail.Fail Code is: "<<nres<<std::endl;
+        if(nres == -1)
+        {
+            std::cout<<" Convert Fail. Please Check Input File"<<std::endl;
+        }
+        if(nres == -2)
+        {
+            std::cout<<" NO Carmaker Service."<<std::endl;
+        }
+        if(nres == -3)
+        {
+            std::cout<<" Server Can't Connect."<<std::endl;
+        }
+        return -3;
+    }
+
+    if(noutputsize == 0)
+    {
+        std::cout<<" Get File size is 0,please check"<<std::endl;
+        return -4;
+    }
+
+    QFile xFileOut;
+    xFileOut.setFileName(gstr_outputpath);
+    if(xFileOut.open(QIODevice::ReadWrite))
+    {
+        xFileOut.write(pout_ptr.get(),noutputsize);
+        xFileOut.close();
+    }
+    else
+    {
+        std::cout<<" Can't Output data to File. "<<" Output Path: "<<gstr_outputpath<<std::endl;
+        return -5;
+    }
+
+    return 0;
+
+
+
+    return a.exec();
+}

+ 38 - 0
src/test/xodr2rd5_grpc/xodr2rd5_grpc.pro

@@ -0,0 +1,38 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += main.cpp \
+    ../carmakerservice/carmaker.grpc.pb.cc \
+    ../../include/msgtype/carmaker.pb.cc \
+    carmakercvt.cpp
+
+INCLUDEPATH += $$PWD/../../../src/include/msgtype
+INCLUDEPATH += $$PWD/../carmakerservice
+
+DEFINES += TESTC
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+!include(../../../include/ivgrpc.pri ) {
+    error( "Couldn't find the ivgrpc.pri file!" )
+}
+
+HEADERS += \
+    ../carmakerservice/carmaker.grpc.pb.h \
+    ../../include/msgtype/carmaker.pb.h \
+    carmakercvt.h