Getting Undefinde symbol from grpc.pb.h

64 views
Skip to first unread message

layla fa

unread,
Nov 11, 2022, 9:55:51 AM11/11/22
to grpc.io
I am writing a gRPC code which is going to converted to .so file and using that shared library I am going to call the service from a mySQl UDF. This is my client.cc:

    #include <grpcpp/grpcpp.h>
    #include <string>
    #include "stringreverse.grpc.pb.h"

    using grpc::Channel;
    using grpc::ClientContext;
    using grpc::Status;

    using stringreverse::StringReply;
    using stringreverse::StringRequest;
    using stringreverse::StringReverse;

    class StringReverseClient {
     public:
      StringReverseClient(std::shared_ptr<Channel> channel)
      : stub_(StringReverse::NewStub(channel)) {}

      // Assembles client payload, sends it to the server, and returns its response
      std::string sendRequest(std::string a) {
    // Data to be sent to server
    StringRequest request;
    request.set_original(a);

    // Container for server response
    StringReply reply;

    // Context can be used to send meta data to server or modify RPC behaviour
    ClientContext context;

    // Actual Remote Procedure Call
    Status status = stub_->sendRequest(&context, request, &reply);

    // Returns results based on RPC status
    if (status.ok()) {
      return reply.reversed();
        } else {
          std::cout << status.error_code() << ": " << status.error_message()
                << std::endl;
          return "RPC Failed";
        }
      }

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

     extern "C" std::string RunClient() {
      std::string target_address("0.0.0.0:50051");
      // Instantiates the client
      StringReverseClient client(
      // Channel from which RPCs are made - endpoint is the target_address
      grpc::CreateChannel(target_address,
                          // Indicate when channel is not authenticated
                          grpc::InsecureChannelCredentials()));

      std::string response;
      std::string a = "grpc is cool!";

      // RPC is created and response is stored
      response = client.sendRequest(a);
 
      // Prints results
      std::cout << "Original string: " << a << std::endl;
      std::cout << "Reversed string: " << response << std::endl;

      return response;
    }
     extern "C" int main(int argc, char* argv[]) {
     RunClient();

      return 0;
    }
this is my stringreverse.proto

    syntax = "proto3";

    package stringreverse;

    // The string reversal service definition.
    service StringReverse {
    // Function invoked to send the request
    rpc sendRequest (StringRequest) returns (StringReply) {}
    }

    // The request message containing the original string
    message StringRequest {
    string original = 1;
    }

    // The response message containing the reversed string
    message StringReply {
    string reversed = 1;
    }
and this is my UDF.cc

     extern "C" std::string stringreverse(UDF_INIT *initid, UDF_ARGS *args,
       std::string result, unsigned long *length,
      char *is_null, char *error)
      {
      void* handle = dlopen("./libclient_lib.so", RTLD_LAZY);
      if (handle == NULL)
      {
          fprintf(stderr, " %s\n", dlerror());

       }
    // load the symbol
    typedef std::string (*RunClient_t)();
    RunClient_t RunClient = (RunClient_t) dlsym(handle, "RunClient");
    result=RunClient();
    dlclose(handle);

    return result;

    }

      extern "C" bool stringreverse_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
      {
   
         return 0;
      }

     extern "C" void stringreverse_init_deinit (UDF_INIT *initid)
     {
      return;
      }
This is server.cc:

    #include <grpcpp/grpcpp.h>
     #include <string>
     #include "stringreverse.grpc.pb.h"

     using grpc::Server;
     using grpc::ServerBuilder;
     using grpc::ServerContext;
     using grpc::Status;

     using stringreverse::StringReply;
     using stringreverse::StringRequest;
    using stringreverse::StringReverse;

      // Server Implementation
      class ReverseServiceImplementation final : public
     StringReverse::Service {
     Status sendRequest(ServerContext* context, const StringRequest*
    request,
                     StringReply* reply) override {
    // Obtains the original string from the request
    std::string a = request->original();

    // String reversal
    int n = a.length();
      for (int i = 0; i < n / 2; i++) std::swap(a[i], a[n - i - 1]);

       reply->set_reversed(a);
       return Status::OK;
     }
    };

     void RunServer() {
     std::string server_address("0.0.0.0:50051");
     ReverseServiceImplementation 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
      // communication with client takes place
      builder.RegisterService(&service);

     // Assembling the server
     std::unique_ptr<Server> server(builder.BuildAndStart());
     std::cout << "Server listening on port: " << server_address <<
    std::endl;

     server->Wait();
    }

     int main(int argc, char** argv) {
     RunServer();
      return 0;
     }
and this is CMAkelists.txt:

     # Minimum CMake required
     cmake_minimum_required(VERSION 3.15)

     # Project
     project(stringreverse)
 
     # Protobuf
     set(protobuf_MODULE_COMPATIBLE TRUE)
     find_package(Protobuf CONFIG REQUIRED)
     message(STATUS "Using protobuf ${protobuf_VERSION}")

    # Protobuf-compiler
    set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)

    # gRPC
    find_package(gRPC CONFIG REQUIRED)
    message(STATUS "Using gRPC ${gRPC_VERSION}")
    set(_GRPC_GRPCPP gRPC::grpc++)
     set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)

    # Proto file
    get_filename_component(hw_proto "stringreverse.proto" ABSOLUTE)
    get_filename_component(hw_proto_path "${hw_proto}" PATH)

    # Generated sources
    set(hw_proto_srcs
    "${CMAKE_CURRENT_BINARY_DIR}/stringreverse.pb.cc")
    set(hw_proto_hdrs
    "${CMAKE_CURRENT_BINARY_DIR}/stringreverse.pb.h")
    set(hw_grpc_srcs
    "${CMAKE_CURRENT_BINARY_DIR}/stringreverse.grpc.pb.cc")
    set(hw_grpc_hdrs
    "${CMAKE_CURRENT_BINARY_DIR}/stringreverse.grpc.pb.h")
     add_custom_command(
        OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}"
     "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
      COMMAND ${_PROTOBUF_PROTOC}
      ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
        --cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
        -I "${hw_proto_path}"
        --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
        "${hw_proto}"
      DEPENDS "${hw_proto}")



     # Include generated *.pb.h files
     include_directories("${CMAKE_CURRENT_BINARY_DIR}")
     include_directories("/home/sama/grpc/include")

     # Targets (client|server)
     foreach(_target
      client server)
      add_executable(${_target} "${_target}.cc"
       ${hw_proto_srcs}
       ${hw_grpc_srcs})
    target_link_libraries(${_target}
        ${_REFLECTION}
        ${_GRPC_GRPCPP}
       ${_PROTOBUF_LIBPROTOBUF})
    endforeach()

    add_library(client_lib SHARED client.cc)
    target_link_libraries(client_lib
         ${_REFLECTION}
        ${_GRPC_GRPCPP}
        ${_PROTOBUF_LIBPROTOBUF}})

First I create libclient_lib.so from my client.cc then use it in my UDF, but I get error ` ./libclient_lib.so: undefined symbol: _ZTVN13stringreverse13StringReverse4Stub5asyncE
Segmentation fault (core dumped)`
I know that the problem is that creating shared library from client.cc when I have class, because when just for testing I remove class and only put a simple function it works. Could you please tell me how should I write client.cc in such a way that I have class and can create shared library from it?

layla fa

unread,
Nov 11, 2022, 9:59:08 AM11/11/22
to grpc.io

The last sentence is not correct and this is what I meant: Could you please tell me how can I solve the problem ? I know that the symbol belongs to stringreverse.grpc.pb.h.

Reply all
Reply to author
Forward
0 new messages