zoukankan      html  css  js  c++  java
  • Windows+Qt使用gRPC

    上篇文章《Windows+VS2017使用gRPC》编译出了Windows下可用的gRPC静态lib库文件,在此基础上要想在Qt上使用,需要使用MSVC2017 64bit构建组件进行构建。

    grpc-server

    新建基于Widget的Qt工程grpc-server

    Widget.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>

    #include <iostream>
    #include <memory>
    #include <string>

    #include <grpcpp/grpcpp.h>

    #include "../grpcSetting/helloworld.grpc.pb.h"

    using grpc::Server;
    using grpc::ServerBuilder;
    using grpc::ServerContext;
    using grpc::Status;
    using helloworld::HelloRequest;
    using helloworld::HelloReply;
    using helloworld::Greeter;

    // Logic and data behind the server's behavior.
    class GreeterServiceImpl final : public Greeter::Service
    {
        Status SayHello(ServerContext *context, 
    const HelloRequest *request,
                        HelloReply *reply) override
        {
            std::string prefix(
    "Hello ");
            reply->set_message(prefix + request->name());
            
    return Status::OK;
        }
    };

    class QTextBrowser;
    class Widget : public QWidget
    {
        Q_OBJECT

    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();

    private slots:
        
    void startServer();

    private:
        QTextBrowser *text;
    };

    #endif // WIDGET_H
    Widget.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    #include "Widget.h"
    #include <QVBoxLayout>
    #include <QTextBrowser>
    #include <QPushButton>

    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , text(
    new QTextBrowser())
    {
        setWindowTitle(tr(
    "grpc-server"));
        resize(
    320460);

        QVBoxLayout *layout = 
    new QVBoxLayout(this);
        QPushButton *button = 
    new QPushButton("Start");
        connect(button, &QPushButton::clicked, 
    this, &Widget::startServer);
        layout->addWidget(text);
        layout->addWidget(button);
        setLayout(layout);
    }

    Widget::~Widget()
    {

    }

    void Widget::startServer()
    {
        std::string server_address(
    "0.0.0.0:50051");
        GreeterServiceImpl service;

        ServerBuilder builder;
        
    // Listen on the given address without any authentication mechanism.
        builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
        
    // 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;
        
    if (text != nullptr)
        {
            text->setText(QString(tr(
    "Server listening on %1")).arg(server_address.c_str()));
        }

        
    // 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();
    }

    grpc-client

    新建基于Widget的Qt工程grpc-client

    Widget.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>

    #include <iostream>
    #include <memory>
    #include <string>

    #include <grpcpp/grpcpp.h>

    #include "../grpcSetting/helloworld.grpc.pb.h"

    using grpc::Channel;
    using grpc::ClientContext;
    using grpc::Status;
    using helloworld::HelloRequest;
    using helloworld::HelloReply;
    using helloworld::Greeter;

    class GreeterClient
    {
    public:
        GreeterClient(std::shared_ptr<Channel> channel)
            : stub_(Greeter::NewStub(channel)) {}

        
    // Assembles the client's payload, sends it and presents the response back
        // from the server.
        std::string SayHello(const std::string &user)
        {
            
    // Data we are sending to the server.
            HelloRequest request;
            request.set_name(user);

            
    // Container for the data we expect from the server.
            HelloReply reply;

            
    // Context for the client. It could be used to convey extra information to
            // the server and/or tweak certain RPC behaviors.
            ClientContext context;

            
    // The actual RPC.
            Status status = stub_->SayHello(&context, request, &reply);

            
    // Act upon its status.
            if (status.ok())
            {
                
    return reply.message();
            }
            
    else
            {
                std::cout << status.error_code() << 
    ": " << status.error_message()
                          << std::endl;
                
    return "RPC failed";
            }
        }

    private:
        std::unique_ptr<Greeter::Stub> stub_;
    };

    class QTextBrowser;
    class Widget : public QWidget
    {
        Q_OBJECT

    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();

    private slots:
        
    void req();

    private:
        QTextBrowser *text;
    };

    #endif // WIDGET_H
    Widget.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    #include "Widget.h"
    #include <QVBoxLayout>
    #include <QTextBrowser>
    #include <QPushButton>

    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , text(
    new QTextBrowser())
    {
        setWindowTitle(tr(
    "grpc-client"));
        resize(
    320460);

        QVBoxLayout *layout = 
    new QVBoxLayout(this);
        QPushButton *button = 
    new QPushButton("req");
        connect(button, &QPushButton::clicked, 
    this, &Widget::req);
        layout->addWidget(text);
        layout->addWidget(button);
        setLayout(layout);
    }

    Widget::~Widget()
    {

    }

    void Widget::req()
    {
        
    // Instantiate the client. It requires a channel, out of which the actual RPCs
        // are created. This channel models a connection to an endpoint (in this case,
        // localhost at port 50051). We indicate that the channel isn't authenticated
        // (use of InsecureChannelCredentials()).
        GreeterClient greeter(grpc::CreateChannel(
                                  
    "localhost:50051", grpc::InsecureChannelCredentials()));
        std::string user(
    "world");
        std::string reply = greeter.SayHello(user);
        std::cout << 
    "Greeter received: " << reply << std::endl;
        
    if (text != nullptr)
        {
            text->setText(QString(
    "Greeter received: %1").arg(reply.c_str()));
        }

    }

    Pro文件设置

    添加预处理器定义:DEFINES += _WIN32_WINNT=0x0A00

    添加链接库以及包含库:这里直接复制过来了,一些冗余的内容可根据实际情况调整

    *.pro
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    INCLUDEPATH += $$PWD/../../../grpc_plugs/grpc/include
    INCLUDEPATH += $$PWD/../../../grpc_plugs/grpc/third_party/protobuf/src
    DEPENDPATH += $$PWD/../../../grpc_plugs/grpc/include


    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/Debug/ -lgrpc++
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/grpc++.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/libgrpc++.a

    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/Debug/ -lgrpc
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/grpc.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/libgrpc.a

    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/Debug/ -lgpr
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/gpr.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/libgpr.a

    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/Debug/ -laddress_sorting
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/address_sorting.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/Debug/libaddress_sorting.a

    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/third_party/protobuf/Debug -llibprotobufd
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/third_party/protobuf/Debug/libprotobufd.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/third_party/protobuf/Debug/liblibprotobufd.a

    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/third_party/zlib/Debug -lzlibd
    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/third_party/zlib/Debug/zlibd.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/third_party/zlib/Debug/libzlibd.a

    win32: LIBS += -L
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64/' -lWS2_32

    INCLUDEPATH += 
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64'
    DEPENDPATH += 
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64'

    win32:!win32-g++: PRE_TARGETDEPS += 
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64/WS2_32.lib'
    else:win32-g++: PRE_TARGETDEPS += 'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64/libWS2_32.a'

    win32: LIBS += -L
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64/' -lAdvapi32

    INCLUDEPATH += 
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64'
    DEPENDPATH += 
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64'

    win32:!win32-g++: PRE_TARGETDEPS += 
    'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64/Advapi32.lib'
    else:win32-g++: PRE_TARGETDEPS += 'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.17763.0/um/x64/libAdvapi32.a'

    win32: LIBS += -L$$PWD/../../../grpc_plugs/grpc/.build/third_party/cares/cares/lib/Debug/ -lcares

    INCLUDEPATH += $$PWD/../../../grpc_plugs/grpc/.build/third_party/cares/cares/lib/Debug
    DEPENDPATH += $$PWD/../../../grpc_plugs/grpc/.build/third_party/cares/cares/lib/Debug

    win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/third_party/cares/cares/lib/Debug/cares.lib
    else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../grpc_plugs/grpc/.build/third_party/cares/cares/lib/Debug/libcares.a

    运行

    参考

    附录

    MinGW使用VS生成的静态库lib文件时,编译不能通过,会提示:
    error: No rule to make target '*.a', needed by '*.exe'. Stop.
    可见它需要的时*.a的静态库文件,而无法使用*.lib的静态库文件。
    但是,MinGW调用linux生成的静态库.a文件,无法链接成功,也无法使用。
    网上流传着这样的资料:
    首先,下载安装MSYS2:http://www.msys2.org/
    (Download and run the installer - "x86_64" for 64-bit, "i686" for 32-bit Windows)
    一路“下一步”就可以安装好MSYS2.
    然后运行msys2.exe脚本,执行如下命令:
    1、pacman -Syu
    2、执行完后,关闭终端,重新打开终端执行:pacman -Su
    3、pacman -S git
    4、pacman -S mingw-w64-i686-grpc
    5、pacman -S mingw-w64-i686-qt5
    6、pacman -S mingw-w64-i686-qt-creator
    之后就可以在安装的qt creator中添加在msys2/mingw32/lib中的grpc静态库和protobuf静态库!!!然后自己根据官网编写简单的C++工程进行测试,只要你库添加的没问题,测试可以通过。
    但是,这个叫MSYS2的类Unix环境安装软件很慢,经常出现安装不成功的问题,很不好使!

  • 相关阅读:
    20200209 ZooKeeper 3. Zookeeper内部原理
    20200209 ZooKeeper 2. Zookeeper本地模式安装
    20200209 Zookeeper 1. Zookeeper入门
    20200206 尚硅谷Docker【归档】
    20200206 Docker 8. 本地镜像发布到阿里云
    20200206 Docker 7. Docker常用安装
    20200206 Docker 6. DockerFile解析
    20200206 Docker 5. Docker容器数据卷
    20200206 Docker 4. Docker 镜像
    Combining STDP and Reward-Modulated STDP in Deep Convolutional Spiking Neural Networks for Digit Recognition
  • 原文地址:https://www.cnblogs.com/MakeView660/p/11512346.html
Copyright © 2011-2022 走看看