Qt 想在windows下運行起grpc服務簡直天坑,在數十次失敗後,用以下方法運行成功。
通過以下網址下載msys2 64位版(32位在windows 10上沒跑起來):
https://www.msys2.org/
安裝完成後,在開始菜單找到並運行“MSYS2 MSYS”,在命令框運行以下命令(10M光纖下載安裝了兩個多小時,請耐心等待):
pacman -Syu
pacman -S mingw-w64-x86_64-grpc mingw-w64-x86_64-qt mingw-w64-x86_64-qt-creator
pacman -S mingw-w64-x86_64-clang
pacman -S mingw-w64-x86_64-qt5-static
“安裝盤\msys64\mingw64\bin” 加下環境變量Path裏。
運行msys64\mingw64\bin\qtcreator.exe,啓動QtCreator,新建Console項目(命名爲QtgRPCConsole)。
爲避免以下錯誤:
配置文件里加入:
DEFINES += _WIN32_WINNT=0x600
右擊項目選擇“添加庫...->外部庫”,指向“msys64\mingw64\lib\libgrpc.dll.a”,取消"爲debug版本添加‘d’作爲後綴"的複選框選項,完成後如下圖:
增加其他grpc和protobuffer庫名到配置文件:
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc_cronet.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc_csharp_ext.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc_plugin_support.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc_unsecure.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc++.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc++_cronet.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc++_error_details.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc++_reflection.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibgrpc++_unsecure.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibprotobuf.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibprotobuf-lite.dll
unix|win32: LIBS += -LD:/msys64/mingw64/lib/ -llibprotoc.dll
INCLUDEPATH += D:/msys64/mingw64/include
DEPENDPATH += D:/msys64/mingw64/include
新建protobuffer文件helloworld.proto:
syntax = "proto3";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
通過protoc生成gRPC類(從mingw/bin下拷貝grpc_cpp_plugin.exe到項目目錄下面):
protoc -I ./ --grpc_out=./ --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe ./helloworld.proto
protoc -I ./ --cpp_out=./ ./helloworld.proto
右擊項目“添加現有文件...”選擇生成的grpc頭文件和類(helloworld.grpc.pb.cc、helloworld.pb.cc、helloworld.grpc.pb.h、helloworld.pb.h)到項目中。
編寫服務端代碼:
#include <QCoreApplication>
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "helloworld.pb.h"
#include "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;
}
};
void RunServer() {
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;
// 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();
}
int main(int argc, char *argv[])
{
// QCoreApplication a(argc, argv);
RunServer();
return 0;
}
運行結果如下:
注:在發佈版本時選擇靜態編譯,然後把grpc的動態鏈接庫放入同文件夾即可執行exe文件。