Greetings

A DLL has been created that will accept any Protobuf message which through 
the use of reflection, will be filled with data from a database and then 
returned to the client. The database table name is mapped to the message 
name and the corresponding table columns are mapped to the message member 
names.

A typical message will have a .proto file as the following:

message OperatingSystemInfo {
    string manufacturer;
    string name;
    string release;
    string osversion;
    string localename;
    string bootdevice;
    string serialnumber;
}

The code snippets for the DLL functions are as follow:

void EXPORT_DLL ReadMessage(void* protoBufMessage) {

      Message* msg = static_cast<Message*>(protoBufMessage);

      const Descriptor* descriptor = msg->GetDescriptor();
      const Reflection* reflection = msg->GetReflection();

      for (int i = 0; i < descriptor->field_count(); i++) {

        const FieldDescriptor* field = descriptor->field(i);
        const FieldDescriptor::Type type = field->type();
        bool isRepeated = field->is_repeated();

        std::string name = field->name();

                            
        if (type == FieldDescriptor::TYPE_MESSAGE) {

        }
        else {
           //read values from database for each corresponding field and set 
value
           string fieldValue;

           SetFieldValues(reflection, field, msg, fieldValue);
        }
    }
}

void SetFieldValues(const google::protobuf::Reflection* reflection,
    const google::protobuf::FieldDescriptor* field,
    google::protobuf::Message* msg,
    std::string fieldValue) {

              switch (field->type()) {
                 case FieldDescriptor::TYPE_STRING:
                    reflection->SetString(msg, field, move(fieldValue))
                 break;

                 case FieldDescriptor::TYPE_UINT32:
                 break;

                 case FieldDescriptor::TYPE_UINT64:
                 break;
         
                 case FieldDescriptor::TYPE_BOOL:
                 break;

                case FieldDescriptor::TYPE_ENUM:
                break;
 
                default:
                break;

              }
}

The client call to the DLL is:

void CallDLL()
{
    OperatingSystemInfo* osi = new OperatingSystemInfo();
    
    ReadMessage(osi);
    
    delete osi;
}

The problem is that when the application is about to terminate, the 
'Destroy' method for the last string in the message, 'serialnumber', causes 
a memory error (__acrt_first_block == header in debug_heap.ccp):

inline void OperatingSystemState::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.manufacturer_.Destroy();
  _impl_.name_.Destroy();
  _impl_.release_.Destroy();
  _impl_.osversion_.Destroy();
  _impl_.localename_.Destroy();
  _impl_.bootdevice_.Destroy();
  _impl_.serialnumber_.Destroy();   //<-----
}

 
void ArenaStringPtr::Destroy() {

  delete tagged_ptr_.GetIfAllocated(); //<----- Line 233 in arenastring.cc 
-> leads to assertion Expession: __acrt_first_block == header in 
debug_heap.ccp
}

Naturally this is an attempt to free an already freed memory.  It is likely 
that allocating the memory outside of the DLL is a factor but the nature of 
the project is such that the DLL has no knowledge of Protobuf message 
types. Hence the reason that reflection is used.

Any helps or hints in resolving this issue is greatly appreciated.


-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/protobuf/38fd946c-f254-446c-aeae-cb9bfa4b136en%40googlegroups.com.

Reply via email to