2

I am using gSOAP to configure an ONVIF compatible camera. Currently, I am manually setting all the parameters in the request by doing something like this. This is for the SetVideEncoderConfiguration

MediaBindingProxy mediaDevice (uri);
AUTHENTICATE (mediaDevice);
_trt__SetVideoEncoderConfiguration req;
_trt__SetVideoEncoderConfigurationResponse resp;
struct tt__VideoEncoderConfiguration encoderConfig;
struct tt__VideoResolution resolutionConfig;
encoderConfig.Name = strdup (name);
encoderConfig.UseCount = 1;
encoderConfig.Quality = 50;

if (strcmp (encoding, "H264") == 0)
encoderConfig.Encoding = tt__VideoEncoding__H264;
else if (strcmp (encoding, "JPEG") == 0)
encoderConfig.Encoding = tt__VideoEncoding__JPEG;

encoderConfig.token = strdup (profileToken);
encoderConfig.SessionTimeout = (LONG64)"PT0S";
resolutionConfig.Width=1280;
resolutionConfig.Height=720;
encoderConfig.Resolution = &resolutionConfig;
tt__VideoRateControl rateControl;
rateControl.FrameRateLimit = 15;
rateControl.EncodingInterval = 1;
rateControl.BitrateLimit = 4500;
encoderConfig.RateControl = &rateControl;
struct tt__H264Configuration h264;
h264.GovLength = 30;
h264.H264Profile = tt__H264Profile__Baseline;
encoderConfig.H264 = &h264;

struct tt__MulticastConfiguration multicast;
struct tt__IPAddress address;
address.IPv4Address = strdup ("0.0.0.0");
multicast.Address = &address;

encoderConfig.Multicast = &multicast;

req.Configuration = &encoderConfig;
req.ForcePersistence = true;



int ret = mediaDevice.SetVideoEncoderConfiguration (&req, resp);
qDebug () << "Set Encoder: " << ret;

Is there an easier way to do this? May be some function calls that set the request parameters? Another way I found with GetMediaUri was to use something like

soap_new_req__trt__GetStreamUri (mediaDevice.soap,soap_new_req_tt__StreamSetup (mediaDevice.soap, (enum tt__StreamType)0, soap_new_tt__Transport(mediaDevice.soap), 1, NULL), "profile1");

Are these the only two ways for client side code with gSOAP?

-Mandar Joshi

mndar
  • 21
  • 2

1 Answers1

4

There are four variations of soap_new_T() to allocate data of type T in C++ with gSOAP:

  • T * soap_new_T(struct soap*) returns a new instance of T that is default initialized and allocated on the heap managed by the soap context.
  • T * soap_new_T(struct soap*, int n) returns an array of n new instances of T on the managed heap. The instances in the array are default initialized as described above.
  • T * soap_new_req_T(struct soap*, ...) (structs and classes only) returns a new instance of T allocated on the managed heap and sets the required data members to the values specified in the other arguments ....
  • T * soap_new_set_T(struct soap*, ...) (structs and classes only) returns a new instance of T on the managed heap and sets the public/serializable data members to the values specified in the other arguments ....

Use soap_strdup(struct soap*, const char*) instead of strdup to dup strings onto the managed heap.

All data on the managed heap is mass-deleted with soap_destroy(soap) and soap_end(soap) (call these in that order) which must be called before soap_done(soap) or soap_free(soap).

To allocate pointers to data, use templates:

template<class T>
T * soap_make(struct soap *soap, T val)
{
  T *p = (T*)soap_malloc(soap, sizeof(T));
  if (p)
    *p = val;
  return p;
}
template<class T>
T **soap_make_array(struct soap *soap, T* array, int n)
{ 
  T **p = (T**)soap_malloc(soap, n * sizeof(T*));
  for (int i = 0; i < n; ++i)
    p[i] = &array[i];
  return p;
}

Then use soap_make<int>(soap, 123) to create a pointer to the value 123 on the managed heap and soap_make_array(soap, soap_new_CLASSNAME(soap, 100), 100) to create 100 pointers to 100 instances of CLASSNAME.

The gSOAP tools also generate deep copy operations for you: CLASSNAME::soap_dup(struct soap*) creates a deep copy of the object and allocates it in a another soap context that you provide as argument. Use NULL as this argument to allocate unmanaged deep copies (but these cannot have pointer cycles!). Then delete unmanaged copies with CLASSNAME::soap_del() for deep deletion of all members and then delete the object itself.

See Memory management in C++ for more details. Use gSOAP 2.8.39 and greater.

Dr. Alex RE
  • 1,772
  • 1
  • 15
  • 23