Segmentation fault when run files generated by protoc - c++

I have generated multiple classes from the protobuf files with the protcompiler. In these classes there is the redefinition of the assignment operator and when I try to make an assagnment the program returns segfault. In particular the error that returns is 0x000000000060be60 in PtrTag (this=0x7f1808001a28) at /usr/include/google/protobuf/metadata_lite.h:136 136 return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask. This function is a library function and I don't know why returns error. There is some library that I have to link in compilation time in addition to the libprotobuf or some object files?
A sample of class generated by protoc is:
class LocalizationEstimate : public ::google::protobuf::Message /* ##protoc_insertion_point(class_definition:apollo.localization.LocalizationEstimate) */ {
public:
LocalizationEstimate();
virtual ~LocalizationEstimate();
LocalizationEstimate(const LocalizationEstimate& from);
inline LocalizationEstimate& operator=(const LocalizationEstimate& from) {
CopyFrom(from);
return *this;
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _internal_metadata_.unknown_fields();
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return _internal_metadata_.mutable_unknown_fields();
}
static const ::google::protobuf::Descriptor* descriptor();
static const LocalizationEstimate& default_instance();
static inline const LocalizationEstimate* internal_default_instance() {
return reinterpret_cast<const LocalizationEstimate*>(
&_LocalizationEstimate_default_instance_);
}
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
1;
void Swap(LocalizationEstimate* other);
// implements Message ----------------------------------------------
inline LocalizationEstimate* New() const PROTOBUF_FINAL { return New(NULL); }
LocalizationEstimate* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void CopyFrom(const LocalizationEstimate& from);
void MergeFrom(const LocalizationEstimate& from);
void Clear() PROTOBUF_FINAL;
bool IsInitialized() const PROTOBUF_FINAL;
size_t ByteSizeLong() const PROTOBUF_FINAL;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const PROTOBUF_FINAL;
void InternalSwap(LocalizationEstimate* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// repeated .apollo.common.TrajectoryPoint trajectory_point = 5;
int trajectory_point_size() const;
void clear_trajectory_point();
static const int kTrajectoryPointFieldNumber = 5;
const ::apollo::common::TrajectoryPoint& trajectory_point(int index) const;
::apollo::common::TrajectoryPoint* mutable_trajectory_point(int index);
::apollo::common::TrajectoryPoint* add_trajectory_point();
::google::protobuf::RepeatedPtrField< ::apollo::common::TrajectoryPoint >*
mutable_trajectory_point();
const ::google::protobuf::RepeatedPtrField< ::apollo::common::TrajectoryPoint >&
trajectory_point() const;
// optional .apollo.common.Header header = 1;
bool has_header() const;
void clear_header();
static const int kHeaderFieldNumber = 1;
const ::apollo::common::Header& header() const;
::apollo::common::Header* mutable_header();
::apollo::common::Header* release_header();
void set_allocated_header(::apollo::common::Header* header);
// optional .apollo.localization.Pose pose = 2;
bool has_pose() const;
void clear_pose();
static const int kPoseFieldNumber = 2;
const ::apollo::localization::Pose& pose() const;
::apollo::localization::Pose* mutable_pose();
::apollo::localization::Pose* release_pose();
void set_allocated_pose(::apollo::localization::Pose* pose);
// optional .apollo.localization.Uncertainty uncertainty = 3;
bool has_uncertainty() const;
void clear_uncertainty();
static const int kUncertaintyFieldNumber = 3;
const ::apollo::localization::Uncertainty& uncertainty() const;
::apollo::localization::Uncertainty* mutable_uncertainty();
::apollo::localization::Uncertainty* release_uncertainty();
void set_allocated_uncertainty(::apollo::localization::Uncertainty* uncertainty);
// optional .apollo.localization.MsfStatus msf_status = 6;
bool has_msf_status() const;
void clear_msf_status();
static const int kMsfStatusFieldNumber = 6;
const ::apollo::localization::MsfStatus& msf_status() const;
::apollo::localization::MsfStatus* mutable_msf_status();
::apollo::localization::MsfStatus* release_msf_status();
void set_allocated_msf_status(::apollo::localization::MsfStatus* msf_status);
// optional .apollo.localization.MsfSensorMsgStatus sensor_status = 7;
bool has_sensor_status() const;
void clear_sensor_status();
static const int kSensorStatusFieldNumber = 7;
const ::apollo::localization::MsfSensorMsgStatus& sensor_status() const;
::apollo::localization::MsfSensorMsgStatus* mutable_sensor_status();
::apollo::localization::MsfSensorMsgStatus* release_sensor_status();
void set_allocated_sensor_status(::apollo::localization::MsfSensorMsgStatus* sensor_status);
// optional double measurement_time = 4;
bool has_measurement_time() const;
void clear_measurement_time();
static const int kMeasurementTimeFieldNumber = 4;
double measurement_time() const;
void set_measurement_time(double value);
// ##protoc_insertion_point(class_scope:apollo.localization.LocalizationEstimate)
private:
void set_has_header();
void clear_has_header();
void set_has_pose();
void clear_has_pose();
void set_has_uncertainty();
void clear_has_uncertainty();
void set_has_measurement_time();
void clear_has_measurement_time();
void set_has_msf_status();
void clear_has_msf_status();
void set_has_sensor_status();
void clear_has_sensor_status();
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::internal::HasBits<1> _has_bits_;
mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::apollo::common::TrajectoryPoint > trajectory_point_;
::apollo::common::Header* header_;
::apollo::localization::Pose* pose_;
::apollo::localization::Uncertainty* uncertainty_;
::apollo::localization::MsfStatus* msf_status_;
::apollo::localization::MsfSensorMsgStatus* sensor_status_;
double measurement_time_;
friend struct protobuf_modules_2flocalization_2fproto_2flocalization_2eproto::TableStruct;
};
Follow the code of the function called in the redefinition of the assignment operator:
void LocalizationEstimate::CopyFrom(const LocalizationEstimate& from) {
// ##protoc_insertion_point(class_specific_copy_from_start:apollo.localization.LocalizationEstimate)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void LocalizationEstimate::MergeFrom(const LocalizationEstimate& from) {
// ##protoc_insertion_point(class_specific_merge_from_start:apollo.localization.LocalizationEstimate)
GOOGLE_DCHECK_NE(&from, this);
_internal_metadata_.MergeFrom(from._internal_metadata_);
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
trajectory_point_.MergeFrom(from.trajectory_point_);
cached_has_bits = from._has_bits_[0];
if (cached_has_bits & 63u) {
if (cached_has_bits & 0x00000001u) {
mutable_header()->::apollo::common::Header::MergeFrom(from.header());
}
if (cached_has_bits & 0x00000002u) {
mutable_pose()->::apollo::localization::Pose::MergeFrom(from.pose());
}
if (cached_has_bits & 0x00000004u) {
mutable_uncertainty()->::apollo::localization::Uncertainty::MergeFrom(from.uncertainty());
}
if (cached_has_bits & 0x00000008u) {
mutable_msf_status()->::apollo::localization::MsfStatus::MergeFrom(from.msf_status());
}
if (cached_has_bits & 0x00000010u) {
mutable_sensor_status()->::apollo::localization::MsfSensorMsgStatus::MergeFrom(from.sensor_status());
}
if (cached_has_bits & 0x00000020u) {
measurement_time_ = from.measurement_time_;
}
_has_bits_[0] |= cached_has_bits;
}
}
In my main function I made somethinghs like:
LocalizationEstimate l = localization;
where localization is a shared variable with an other process. But this assignment return segfault.

Related

c++ polymorphism with class template, no matching function to call

I'm writing a class template that can take one of the following, int8_t, int16_t, int32_t, float and double. Here it is:
#ifndef OPERAND_HPP
# define OPERAND_HPP
# include "IOperand.hpp"
# include <regex>
template <typename T>
class Operand : public IOperand {
private:
/* Constructors - Destructors */
Operand() = default;
/* Attributes */
T _num;
eOperandType const _type;
std::string const &_value;
/* Static functions */
static int8_t getValue(Operand<int8_t> const *it) { return it->getNum(); }
static int16_t getValue(Operand<int16_t> const *it) { return it->getNum(); }
static int32_t getValue(Operand<int32_t> const *it) { return it->getNum(); }
static float getValue(Operand<float> const *it) { return it->getNum(); }
static double getValue(Operand<double> const *it) { return it->getNum(); }
public:
/* Constructors - Destructors */
explicit Operand(eOperandType t, std::string const &v, T n) : _num(n), _type(t), _value(v) {}
Operand(Operand const &rhs) : Operand(rhs.getType(), rhs.toString(), rhs.getNum()) {};
~Operand() override = default;
/* Operator overloads */
Operand<T> &operator=(Operand const &rhs) {
_num = rhs.getNum();
_type = rhs.getType();
_value = rhs.toString();
return *this;
}
IOperand const *operator+(IOperand const &rhs) const final {
Operand::getValue(&rhs);
return &rhs;
}
IOperand const *operator-(IOperand const &rhs) const final { return &rhs; }
IOperand const *operator*(IOperand const &rhs) const final { return &rhs; }
IOperand const *operator/(IOperand const &rhs) const final { return &rhs; }
IOperand const *operator%(IOperand const &rhs) const final { return &rhs; }
/* ------------------------------------------------- Exceptions ------------------------------------------------- */
class DivisionByZero : public std::exception {
public:
char const *what() const noexcept final { return "division by zero"; }
};
class ModuloByZero : public std::exception {
public:
char const *what() const noexcept final { return "modulo by zero"; }
};
class Overflow : public std::exception {
public:
char const *what() const noexcept final { return "overflow"; }
};
class Underflow : public std::exception {
public:
char const *what() const noexcept final { return "underflow"; }
};
/* -------------------------------------------------------------------------------------------------------------- */
/* Member functions */
T getNum() const { return _num; }
int getPrecision() const final { return static_cast<int>(_type); }
eOperandType getType() const final { return _type; }
std::string const &toString() const final { return _value; }
};
#endif /* OPERAND_HPP */
That class inherit from the following interface:
#ifndef IOPERAND_HPP
# define IOPERAND_HPP
# include <string>
enum eOperandType {
INT8,
INT16,
INT32,
FLOAT,
DOUBLE
};
class IOperand {
public:
/* Constructors - Destructors */
virtual ~IOperand() = default;
/* Operator overloads */
virtual IOperand const *operator+(IOperand const &) const = 0;
virtual IOperand const *operator-(IOperand const &) const = 0;
virtual IOperand const *operator*(IOperand const &) const = 0;
virtual IOperand const *operator/(IOperand const &) const = 0;
virtual IOperand const *operator%(IOperand const &) const = 0;
/* Member functions */
virtual int getPrecision() const = 0;
virtual eOperandType getType() const = 0;
virtual std::string const &toString() const = 0;
};
#endif /* IOPERAND_HPP */
I'm struggling to implement the + operator overload. That function has two IOperand & as arguments, but I need to access the _num attribute of said arguments. The getter for this attribute isn't in the base class, only in the derived class. I tried polymorphism with the following functions:
static int8_t getValue(Operand<int8_t> const *it) { return it->getNum(); }
static int16_t getValue(Operand<int16_t> const *it) { return it->getNum(); }
static int32_t getValue(Operand<int32_t> const *it) { return it->getNum(); }
static float getValue(Operand<float> const *it) { return it->getNum(); }
static double getValue(Operand<double> const *it) { return it->getNum(); }
but I get the following error message when compiling with clang++:
./Operand.tpp:41:15: error: no matching function for call to 'getValue'
(void)Operand::getValue(&rhs);
./Operand.tpp:19:29: note: candidate function not viable: cannot convert from base class pointer 'const IOperand *' to derived class pointer 'const Operand<int8_t> *'
(aka 'const Operand<signed char> *') for 1st argument
static int8_t getValue(Operand<int8_t> const *it) { return it->getNum(); }
The error message is pretty verbose and I understand where the problem lies. However I'm not sure how to fix it, or if there would be a more elegant approach to my problem. I could probably get away with it using dynamic casts, or even using 5 different classes instead of a template, but it doesn't seem that good.
Could anyone point me in the right direction?

How to refactor method using template in C++

I am in need to (or better, I have the chance to) refactor some code in order to make it cleaner.
I would like to use some template, as I think this is a good candidate, in order to reduce the code duplication.
Here is my hpp
class Monetary
{
public:
Monetary();
Monetary(const rapidjson::Value& iMonetary);
virtual ~Monetary();
[...cut...]
private:
static void initMember(const rapidjson::Value& iMonetary, const char* iName, int& oMember);
static void initMember(const rapidjson::Value& iMonetary, const char* iName, std::string& oMember);
private:
int _amount;
int _decimal_place;
std::string _currency;
std::string _type;
};
And here is the implementation for the the initMember methods:
static void Monetary::initMember(const rapidjson::Value& iMonetary, const char* iName, int& oMember)
{
rapidjson::Value::ConstMemberIterator aIterator;
aIterator = iMonetary.FindMember(iName);
if ( aIterator != iMonetary.MemberEnd() &&
aIterator->value.IsNumber() )
{
oMember = iMonetary[iName].GetInt();
}
}
static void Monetary::initMember(const rapidjson::Value& iMonetary, const char* iName, std::string& oMember)
{
rapidjson::Value::ConstMemberIterator aIterator;
aIterator = iMonetary.FindMember(iName);
if ( aIterator != iMonetary.MemberEnd() &&
aIterator->value.IsNumber() )
{
oMember = iMonetary[iName].GetString();
}
}
I was thinking about writing something like
template<typename T>
void Monetary::initMember(const rapidjson::Value& iMonetary, const char* iName, T& oMember)
{
rapidjson::Value::ConstMemberIterator aIterator;
aIterator = iMonetary.FindMember(iName);
if (aIterator == iMonetary.MemberEnd())
{
return;
//throw monetaryException
}
assignFromValue(iMonetary[iName], oMember);
}
template<>
void Monetary::assignFromValue<int>(const rapidjson::Value& iValue, int& oMember)
{
if (!iValue.IsNumber())
{
return;
//throw monetaryException
}
oMember = iValue.GetInt();
}
template<>
void Monetary::assignFromValue<std::string>(const rapidjson::Value& iValue, std::string& oMember)
{
if (!iValue.IsString())
{
return;
//throw monetaryException
}
oMember = iValue.GetString();
}
Is there any clewer way to do that ?
My suggestions:
You don't need to make assignFromValue member functions. If you can implement functionality using non-member functions, you should prefer non-member functions. See How Non-Member Functions Improve Encapsulation and How Non-Member Functions Improve Encapsulation.
You don't need to make assignFromValue function templates. They can be simple overloads.
void assignFromValue(const rapidjson::Value& iValue,
int& oMember)
{
if (!iValue.IsNumber())
{
return;
//throw monetaryException
}
oMember = iValue.GetInt();
}
void assignFromValue(const rapidjson::Value& iValue,
std::string& oMember)
{
if (!iValue.IsString())
{
return;
//throw monetaryException
}
oMember = iValue.GetString();
}
I think I'd do it with a tag-dispatched converter object:
#include <string>
#include <type_traits>
#include <stdexcept>
// simulate your value class
struct Value
{
bool IsNumber() const;
bool IsString() const;
std::string getString() const;
int getInt() const;
};
// a tag type for easy tag dispatching
template<class Type> struct tag {};
// a converter object contains all rules and conversion sequences
struct ValueConverter
{
std::string operator()(tag<std::string>, const Value& v) const
{
if (not v.IsString()) throw std::invalid_argument("not a string");
return v.getString();
}
int operator()(tag<int>, const Value& v) const
{
if (not v.IsNumber()) throw std::invalid_argument("not a number");
return v.getInt();
}
};
// write the member once
template<class Target>
void initMember(const Value& iMonetary, const char* iName, Target& oMember)
{
using target_type = std::decay_t<Target>;
auto converter = ValueConverter();
oMember = converter(tag<target_type>(), iMonetary);
}

How do I call a child's overloaded operator from a function in the parent class which has a reference to the parent as a parameter?

How do I get an overloaded relational operator in a class to be called from a function in the parent class that is handed a const reference to a base class as a parameter? The following code demonstrates what I would like to do:
class Object
{
public:
virtual ~Object(void);
virtual int compare(Object const& obj) const;
};
int Object::compare(Object const & obj) const {
if(this == &obj)
{
return 0;
}
else if(this < &obj)
{
return -1;
} else{
return 1;
}
}
class Integer: public Object
{
private:
int myInt;
public:
Integer(int i);
bool operator==(const Integer& integer);
};
bool Integer::operator==(Integer const &integer) {
if(myInt == integer.myInt)
{
return true;
}
return false;
}
How do I get the compare function in the base class to call the == operator in the child class, keeping in mind I have other child classes as well?
I have tried dynamic_cast<> but for some reason it wont work.
You can add another virtual method isEqual to connect with the Integer::operator==.
The only requirement is to keep the Object::isEqual signature in the class Integer. You should also keep in mind that your Object::compare method can be (accidentally) called on objects of different types.
class Object
{
protected:
virtual bool isEqual(Object const& obj) const
{ return this == &obj; }
public:
virtual ~Object(void);
virtual int compare(Object const& obj) const;
};
int Object::compare(Object const & obj) const {
if(isEqual(obj))
{
return 0;
}
else if(this < &obj)
{
return -1;
} else{
return 1;
}
}
class Integer: public Object
{
private:
int myInt;
protected:
virtual bool isEqual(Object const& obj) const
{ if (!dynamic_cast<const Integer*>(&obj))
return false;
return *this == (const Integer&) obj;
}
public:
Integer(int i);
bool operator==(const Integer& integer);
};
I would do:
#include <iostream>
class Object
{
public:
virtual ~Object(void) {};
int compare(Object const& obj) const;
virtual bool operator==(Object const& integer) const = 0;
virtual bool operator<(Object const& integer) const = 0;
virtual bool operator>(Object const& integer) const = 0;
};
int Object::compare(Object const& obj) const
{
if(*this == obj)
return 0;
else if(*this < obj)
return -1;
else return 1;
}
class Integer: public Object
{
private:
int myInt;
public:
Integer(int i) : myInt(i) { };
virtual bool operator==(Object const& integer) const override;
virtual bool operator<(Object const& integer) const override;
virtual bool operator>(Object const& integer) const override;
};
bool Integer::operator==(Object const& integer) const
{
return myInt == dynamic_cast<Integer const&>(integer).myInt;
}
bool Integer::operator<(Object const& integer) const
{
return myInt < dynamic_cast<Integer const&>(integer).myInt;
}
bool Integer::operator>(Object const& integer) const
{
return myInt > dynamic_cast<Integer const&>(integer).myInt;
}
int main()
{
Integer a(2), b(2), c(3);
std::cout << a.compare(b) << std::endl;
std::cout << b.compare(c) << std::endl;
std::cout << c.compare(a) << std::endl;
}
But in reality you should just provide virtual compare function in inherited class like so:
class Object
{
public:
virtual ~Object(void) {};
virtual int compare(Object const& obj) const = 0;
};
class Integer: public Object
{
private:
int myInt;
public:
Integer(int i) : myInt(i) { };
virtual int compare(Object const& object) const override;
bool operator==(Integer const& integer) const;
bool operator<(Integer const& integer) const;
bool operator>(Integer const& integer) const;
};
int Integer::compare(Object const& object) const
{
Integer const& ref = dynamic_cast<Integer const&>(object);
if(ref == *this)
return 0;
else if(ref > *this)
return 1;
else return -1;
}
bool Integer::operator==(Integer const& integer) const
{
return myInt == integer.myInt;
}
bool Integer::operator<(Integer const& integer) const
{
return myInt > integer.myInt;
}
bool Integer::operator>(Integer const& integer) const
{
return myInt < integer.myInt;
}

How to set field of a nested message in protocol buffers?

I have a proto file that looks like this:
message terminal_data
{
required int32 type = 1; //1-->trade 2-->order
message trade_data
{
optional string client_id = 1;
optional string strat_id = 2;
optional string symbol_name = 3;
optional int64 trade_id = 4;
optional string expiry = 5;
optional int64 quantity = 6;
optional string time = 7;
}
message order_data
{
optional string client_id = 1;
optional string strat_id = 2;
optional string symbol_name = 3;
optional int64 order_id = 4;
optional string side = 5;
optional int64 quantity = 6;
optional string time = 7;
}
}
Now to set data, I am doing this:
tData.trade_data.mutable_client_id();
It complains:
:
error: invalid use of 'data_model::terminal_data::trade_data'
tData.trade_data.mutable_client_id();
^
What is the correct way to set the nested message ?
Here is the generated code:
class terminal_data : public ::google::protobuf::Message {
public:
terminal_data();
virtual ~terminal_data();
terminal_data(const terminal_data& from);
inline terminal_data& operator=(const terminal_data& from) {
CopyFrom(from);
return *this;
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _unknown_fields_;
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return &_unknown_fields_;
}
static const ::google::protobuf::Descriptor* descriptor();
static const terminal_data& default_instance();
void Swap(terminal_data* other);
// implements Message ----------------------------------------------
terminal_data* New() const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
void CopyFrom(const terminal_data& from);
void MergeFrom(const terminal_data& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::google::protobuf::Metadata GetMetadata() const;
// nested types ----------------------------------------------------
typedef terminal_data_trade_data trade_data;
typedef terminal_data_order_data order_data;
// accessors -------------------------------------------------------
// required int32 type = 1;
inline bool has_type() const;
inline void clear_type();
static const int kTypeFieldNumber = 1;
inline ::google::protobuf::int32 type() const;
inline void set_type(::google::protobuf::int32 value);
// ##protoc_insertion_point(class_scope:data_model.terminal_data)
private:
inline void set_has_type();
inline void clear_has_type();
::google::protobuf::UnknownFieldSet _unknown_fields_;
::google::protobuf::int32 type_;
mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
friend void protobuf_AddDesc_data_5fmodel_2eproto();
friend void protobuf_AssignDesc_data_5fmodel_2eproto();
friend void protobuf_ShutdownFile_data_5fmodel_2eproto();
void InitAsDefaultInstance();
static terminal_data* default_instance_;
};
The proto definition of terminal_data defines a nested message trade_data - but it doesn't actually define a field whose type is that message. terminal_data only has one field, type. Add something like
optional trade_data trade = 2;
optional order_data order = 3;
It's exactly like in C++, you can write
class Outer {
class Inner {};
};
Just because you've defined a nested class, doesn't mean the outer class magically acquires a member whose type is that nested class.

protobuf can't be serialized

hello eyeryone,
my protobuf version is 2.5.0, the generated header file just contains a SerializeWithCachedSizes method, I want to serialize my protobuf object to char array, and post the array by socket. in lots of tutorials refer to a method SerializeToArray method, I just need this method, but why my header file doesn't contains this method?
the first time to use protobuf, not familiar with that. if anyone can solve the problem, please show me the detail code.
proto file as:
package ddz.proto;
option optimize_for = LITE_RUNTIME;
option java_package = "ddz.proto";
option java_outer_classname = "Login";
message LoginMessage {
optional string userAccount = 1;
}
and generated header file as:
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: hello.proto
#ifndef PROTOBUF_hello_2eproto__INCLUDED
#define PROTOBUF_hello_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 2005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
// ##protoc_insertion_point(includes)
namespace ddz {
namespace proto {
// Internal implementation detail -- do not call these.
void protobuf_AddDesc_hello_2eproto();
void protobuf_AssignDesc_hello_2eproto();
void protobuf_ShutdownFile_hello_2eproto();
class LoginMessage;
// ===================================================================
class LoginMessage : public ::google::protobuf::MessageLite {
public:
LoginMessage();
virtual ~LoginMessage();
LoginMessage(const LoginMessage& from);
inline LoginMessage& operator=(const LoginMessage& from) {
CopyFrom(from);
return *this;
}
static const LoginMessage& default_instance();
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
// Returns the internal default instance pointer. This function can
// return NULL thus should not be used by the user. This is intended
// for Protobuf internal code. Please use default_instance() declared
// above instead.
static inline const LoginMessage* internal_default_instance() {
return default_instance_;
}
#endif
void Swap(LoginMessage* other);
// implements Message ----------------------------------------------
LoginMessage* New() const;
void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
void CopyFrom(const LoginMessage& from);
void MergeFrom(const LoginMessage& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::std::string GetTypeName() const;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// optional string userAccount = 1;
inline bool has_useraccount() const;
inline void clear_useraccount();
static const int kUserAccountFieldNumber = 1;
inline const ::std::string& useraccount() const;
inline void set_useraccount(const ::std::string& value);
inline void set_useraccount(const char* value);
inline void set_useraccount(const char* value, size_t size);
inline ::std::string* mutable_useraccount();
inline ::std::string* release_useraccount();
inline void set_allocated_useraccount(::std::string* useraccount);
// ##protoc_insertion_point(class_scope:ddz.proto.LoginMessage)
private:
inline void set_has_useraccount();
inline void clear_has_useraccount();
::std::string* useraccount_;
mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
friend void protobuf_AddDesc_hello_2eproto_impl();
#else
friend void protobuf_AddDesc_hello_2eproto();
#endif
friend void protobuf_AssignDesc_hello_2eproto();
friend void protobuf_ShutdownFile_hello_2eproto();
void InitAsDefaultInstance();
static LoginMessage* default_instance_;
};
// ===================================================================
// ===================================================================
// LoginMessage
// optional string userAccount = 1;
inline bool LoginMessage::has_useraccount() const {
return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void LoginMessage::set_has_useraccount() {
_has_bits_[0] |= 0x00000001u;
}
inline void LoginMessage::clear_has_useraccount() {
_has_bits_[0] &= ~0x00000001u;
}
inline void LoginMessage::clear_useraccount() {
if (useraccount_ != &::google::protobuf::internal::kEmptyString) {
useraccount_->clear();
}
clear_has_useraccount();
}
inline const ::std::string& LoginMessage::useraccount() const {
return *useraccount_;
}
inline void LoginMessage::set_useraccount(const ::std::string& value) {
set_has_useraccount();
if (useraccount_ == &::google::protobuf::internal::kEmptyString) {
useraccount_ = new ::std::string;
}
useraccount_->assign(value);
}
inline void LoginMessage::set_useraccount(const char* value) {
set_has_useraccount();
if (useraccount_ == &::google::protobuf::internal::kEmptyString) {
useraccount_ = new ::std::string;
}
useraccount_->assign(value);
}
inline void LoginMessage::set_useraccount(const char* value, size_t size) {
set_has_useraccount();
if (useraccount_ == &::google::protobuf::internal::kEmptyString) {
useraccount_ = new ::std::string;
}
useraccount_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* LoginMessage::mutable_useraccount() {
set_has_useraccount();
if (useraccount_ == &::google::protobuf::internal::kEmptyString) {
useraccount_ = new ::std::string;
}
return useraccount_;
}
inline ::std::string* LoginMessage::release_useraccount() {
clear_has_useraccount();
if (useraccount_ == &::google::protobuf::internal::kEmptyString) {
return NULL;
} else {
::std::string* temp = useraccount_;
useraccount_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
return temp;
}
}
inline void LoginMessage::set_allocated_useraccount(::std::string* useraccount) {
if (useraccount_ != &::google::protobuf::internal::kEmptyString) {
delete useraccount_;
}
if (useraccount) {
set_has_useraccount();
useraccount_ = useraccount;
} else {
clear_has_useraccount();
useraccount_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// ##protoc_insertion_point(namespace_scope)
} // namespace proto
} // namespace ddz
// ##protoc_insertion_point(global_scope)
#endif // PROTOBUF_hello_2eproto__INCLUDED
The method, SerializeToArray is defined as "bool SerializeToArray(void* data, int size) const;" within the message_lite.h file.
I can see that #include has been defined in your 'hello.proto' file. So you should have access to this function within your calling program.
See the example at proto file and call to Serialize method at https://stackoverflow.com/a/23945901/3685825
In past, I have pushed the serialized data across the socket. You may need to consider adding message Length before the actual message and send it across socket.
See the example at https://stackoverflow.com/a/11339251/3685825
Hope this helps!