Skip to content

Instantly share code, notes, and snippets.

@mikolasan
Last active June 9, 2023 18:47
Show Gist options
  • Save mikolasan/1f8f61a0b6e06337b6e0264222ca8545 to your computer and use it in GitHub Desktop.
Save mikolasan/1f8f61a0b6e06337b6e0264222ca8545 to your computer and use it in GitHub Desktop.
Memory handle examples

C++ MemoryHandle struct definition

Another process

Generate C++ code for the gRPC service

protoc --grpc_out=. --cpp_out=. memory.proto

Strange issue in my Arch install. Here's the full command:

protoc --grpc_out=. --cpp_out=. --plugin="protoc-gen-grpc=/usr/bin/grpc_cpp_plugin" memory.proto

Build

g++ -o grpc_server memory.pb.cc memory.grpc.pb.cc grpc_server.cpp -lprotobuf `pkg-config grpc++ --libs`
g++ -o grpc_test memory.pb.cc memory.grpc.pb.cc grpc_test.cpp -lprotobuf `pkg-config grpc++ --libs`

Note: here's an approximate output for pkg-config grpc++ --libs:

-lgrpc++ -lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -lgpr -lssl -lcrypto -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_hash -labsl_city -labsl_low_level_hash -labsl_random_distributions -labsl_random_seed_sequences -labsl_random_internal_pool_urbg -labsl_random_internal_randen -labsl_random_internal_randen_hwaes -labsl_random_internal_randen_hwaes_impl -labsl_random
_internal_randen_slow -labsl_random_internal_platform -labsl_random_internal_seed_material -labsl_random_seed_gen_exception -labsl_statusor -labsl_status -labsl_cord -labsl_cordz_info -labsl_cord_internal -labsl_cordz_functions -labsl_exponential_biased -labsl_cordz_handle -labsl_bad_optional_access -labsl_strerror -labsl_str_format_internal -labsl_synchronization -labsl_graphcy
cles_internal -labsl_stacktrace -labsl_symbolize -labsl_debugging_internal -labsl_demangle_internal -labsl_malloc_internal -labsl_time -labsl_civil_time -labsl_strings -labsl_strings_internal -lrt -labsl_base -labsl_spinlock_wait -labsl_int128 -labsl_throw_delegate -labsl_time_zone -labsl_bad_variant_access -labsl_raw_logging_internal -labsl_log_severity

Run

Terminal 1

./grpc_server

Terminal 2

./grpc_test

The Cloud

Install the AWS SDK for C++

git clone https://github.com/aws/aws-sdk-cpp.git
cd aws-sdk-cpp
mkdir build && cd build
cmake .. -DBUILD_ONLY="s3" -DCMAKE_INSTALL_PREFIX=<path/to/install/dir>
make
make install

Reference

LICENSE

All code is generated by ChatGPT

https://twitter.com/mikolasan/status/1640814164745818112

#include <aws/core/Aws.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/s3/model/GetObjectRequest.h>
#include "MemoryHandle.h"
int main(int argc, char** argv) {
// Initialize the AWS SDK
Aws::SDKOptions options;
Aws::InitAPI(options);
// Set up the S3 client
Aws::Client::ClientConfiguration config;
config.region = "us-east-1"; // Change to your desired region
Aws::S3::S3Client s3_client(config);
// Allocate some memory using the MemoryHandle structure
MemoryHandle handle;
handle.size = 1024;
handle.address = new char[handle.size];
std::memset(handle.address, 0, handle.size);
// Upload the data to S3
Aws::S3::Model::PutObjectRequest request;
request.SetBucket("my-bucket");
request.SetKey("my-object");
request.SetBody(Aws::Utils::ByteBuffer(reinterpret_cast<unsigned char*>(handle.address), handle.size));
auto outcome = s3_client.PutObject(request);
if (!outcome.IsSuccess()) {
std::cerr << "Failed to upload object to S3: " << outcome.GetError().GetMessage() << std::endl;
return 1;
}
// Download the data from S3
Aws::S3::Model::GetObjectRequest get_request;
get_request.SetBucket("my-bucket");
get_request.SetKey("my-object");
auto get_outcome = s3_client.GetObject(get_request);
if (!get_outcome.IsSuccess()) {
std::cerr << "Failed to download object from S3: " << get_outcome.GetError().GetMessage() << std::endl;
return 1;
}
// Copy the downloaded data into a new MemoryHandle structure
MemoryHandle download_handle;
download_handle.size = get_outcome.GetResult().GetContentLength();
download_handle.address = new char[download_handle.size];
std::memcpy(download_handle.address, get_outcome.GetResult().GetBody().GetUnderlyingData(), download_handle.size);
// Cleanup
delete[] handle.address;
delete[] download_handle.address;
// Shutdown the AWS SDK
Aws::ShutdownAPI(options);
return 0;
}
#include <grpcpp/grpcpp.h>
#include "memory_handle.h"
#include "memory.pb.h"
#include "memory.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using memory::MemoryRequest;
using memory::MemoryResponse;
using memory::MemoryService;
class MemoryServiceImpl final : public MemoryService::Service {
public:
Status GetMemorySize(ServerContext* context, const MemoryRequest* request, MemoryResponse* response) override {
// Allocate some memory using the MemoryHandle structure
MemoryHandle handle;
handle.size = 1024;
handle.address = new char[handle.size];
std::memset(handle.address, 0, handle.size);
// Fill in the response with the data from the MemoryHandle structure
response->set_size(handle.size);
response->set_data(handle.address, handle.size);
// Cleanup
delete[] handle.address;
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
MemoryServiceImpl service;
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main(int argc, char** argv) {
RunServer();
return 0;
}
#include <grpcpp/grpcpp.h>
#include "memory.pb.h"
#include "memory.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using memory::MemoryHandle;
using memory::MemoryRequest;
using memory::MemoryResponse;
using memory::MemoryService;
class MemoryClient {
public:
MemoryClient(std::shared_ptr<Channel> channel)
: stub_(MemoryService::NewStub(channel)) {}
uint64_t GetMemorySize(const MemoryHandle& handle) {
MemoryRequest request;
request.mutable_handle()->CopyFrom(handle);
MemoryResponse response;
ClientContext context;
Status status = stub_->GetMemorySize(&context, request, &response);
if (status.ok()) {
return response.size();
} else {
std::cout << "RPC failed: " << status.error_message() << std::endl;
return 0;
}
}
private:
std::unique_ptr<MemoryService::Stub> stub_;
};
int main(int argc, char** argv) {
MemoryHandle handle;
handle.set_size(1024);
MemoryClient client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
uint64_t size = client.GetMemorySize(handle);
std::cout << "Size of allocated memory: " << size << std::endl;
return 0;
}
syntax = "proto3";
package memory;
service MemoryService {
rpc GetMemorySize(MemoryRequest) returns (MemoryResponse) {}
}
message MemoryHandle {
uint64 size = 1;
}
message MemoryRequest {
MemoryHandle handle = 1;
}
message MemoryResponse {
uint64 size = 1;
string data = 2;
}
#include <stdint.h>
#include <time.h>
struct Linkable {};
struct MemoryHandle
{
volatile struct Linkable free_node;
char *channel_name;
uint64_t size;
uint32_t mem_flags;
uint32_t type;
int32_t fd;
int32_t pid;
time_t created;
time_t last_access;
char *address;
};
@mikolasan
Copy link
Author

Did you manage to fix it?

Oh yes! So, this error happens when you run grpc_test solely (check here code of grpc_test.cpp). But it is a client application and it tries to connect to the server. So you need to implement and run the server first. From code generated by proto you need to inherit from a ::Service class. Check here code of grpc_server.cpp.

I know this tutorial is wordy and boring, but it explains how to use that generated code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment