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.
On Friday, November 11, 2022 at 3:55:51 PM UTC+1 layla fa wrote: > 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? > -- You received this message because you are subscribed to the Google Groups "grpc.io" group. To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/4c4ecad6-5b3e-452f-b399-3a673e15327en%40googlegroups.com.