How to properly wrap a C-Library

Discussion in 'C++' started by Torsten, Jul 27, 2010.

  1. Torsten

    Torsten Guest

    Hello,

    I'am currently wrapping a c-style library for using a camera and I am
    not sure, how to handle errors.

    The API of the camera has functions for sending commands to the camera
    and querying the cameras response from the camera:

    int write(void* handle, char* command, long timeout)
    int read(void* handle, char** response, size_t buffersize, long timeout)

    Both return an error code, since the commands can fail for several
    reasons that are not in the scope of the programmer (camera timeout,
    camera not connected, ...).

    No I want to wrap this library. A member function of the camera shall
    send a command to the camera and return it's response, e.g.

    std::string Camera::sendCommand(const std::string &command);

    My question: what is the best way to handle these errors:

    1. Throw exceptions and wrap every sendCommand in a try/catch block?
    This makes the calling code quite ugly.
    2. Provide an error() function, that can be called after sending the
    command?
    3. Make the reponse an output parameter and return an error code?
    bool sendCommand(const std::string &command, std::string &response);

    Can someone give me an advice?

    Thanks, Torsten
     
    Torsten, Jul 27, 2010
    #1
    1. Advertising

  2. * Torsten, on 27.07.2010 11:26:
    > Hello,
    >
    > I'am currently wrapping a c-style library for using a camera and I am
    > not sure, how to handle errors.
    >
    > The API of the camera has functions for sending commands to the camera
    > and querying the cameras response from the camera:
    >
    > int write(void* handle, char* command, long timeout)
    > int read(void* handle, char** response, size_t buffersize, long timeout)
    >
    > Both return an error code, since the commands can fail for several
    > reasons that are not in the scope of the programmer (camera timeout,
    > camera not connected, ...).
    >
    > No I want to wrap this library. A member function of the camera shall
    > send a command to the camera and return it's response, e.g.
    >
    > std::string Camera::sendCommand(const std::string &command);
    >
    > My question: what is the best way to handle these errors:
    >
    > 1. Throw exceptions and wrap every sendCommand in a try/catch block?
    > This makes the calling code quite ugly.
    > 2. Provide an error() function, that can be called after sending the
    > command?
    > 3. Make the reponse an output parameter and return an error code?
    > bool sendCommand(const std::string &command, std::string &response);
    >
    > Can someone give me an advice?


    When you're unsure what the right approach is, that probably means that you can
    see some situations where exceptions might be most practical, and some
    situations where return codes might be practical.

    So provide both.

    Not everything is either/or. :)


    Cheers & hth.,

    - Alf

    --
    blog at <url: http://alfps.wordpress.com>
     
    Alf P. Steinbach /Usenet, Jul 27, 2010
    #2
    1. Advertising

  3. Torsten

    Torsten Guest

    On 27/07/10 17:17, Max wrote:
    >> I'am currently wrapping a c-style library for using a camera and I
    >> am not sure, how to handle errors.

    >
    > Why do you wrap it? Which problem are you trying to solve?


    Well, I want my application to support different types fo cameras, e.g.
    CameraLink or GigE cameras. Therefore, I have to provide a common
    interface for all types of cameras. The c-style library is acutally the
    CameraLink library.

    Torsten
     
    Torsten, Jul 27, 2010
    #3
  4. Torsten

    Torsten Guest

    >> [...]
    >>
    >> int write(void* handle, char* command, long timeout)
    >> int read(void* handle, char** response, size_t buffersize, long timeout)
    >>
    >> Both return an error code, since the commands can fail for several
    >> reasons that are not in the scope of the programmer (camera timeout,
    >> camera not connected, ...).
    >>
    >> No I want to wrap this library. A member function of the camera shall
    >> send a command to the camera and return it's response, e.g.
    >>
    >> std::string Camera::sendCommand(const std::string &command);
    >>
    >> My question: what is the best way to handle these errors:

    >
    > What exactly should happen when the camera is not connected or when a
    > timeout occurs?


    On a timeout, I would like to try to send the command once more, maybe
    write a log message, and inform the user. When the camera in not
    connected, I would like to inform the usere immediately. Many differnt
    approaches are possible. I haven't decides that yet.

    > For example, if there's just a message to be displayed to the user, then
    > I don't see how the use of exceptions could possibly lead to all
    > sendCommand calls being wrapped in try/catch blocks.


    The code to send the command for setting gain to a special value a
    second time if it was not successfull the first time, might look like:

    try {
    // send it the first time:
    camera.sendCommand("set gain to value xyz");
    }
    catch(TimoutException)
    {
    // send it the second time:
    camera.sendCommand("set gain to value xyz");
    // don't catch the exception, if it fails twice
    }

    Doesn't look very nice to me.

    > It seems that you are too quick to think in in low-level terms here.
    > Before deciding on how error handling should be implemented you should
    > decide on what the error handling should do.


    Hmm, ok. Maybe, I need to first decide, what to do when errors occur.
    The rational behind throwing an exception was, that the CameraLink class
    has no way to deal with these errors. They are out of there scope, and
    so I thought, this really sounds like an exception.

    On the other hand, this try/catch code above doesn't look very elegant
    to me. Do I overlook a 'good looking' solution?

    Torsten
     
    Torsten, Jul 27, 2010
    #4
  5. Torsten

    Daniel Pitts Guest

    On 7/27/2010 8:48 AM, Torsten wrote:
    >>> [...]
    >>>
    >>> int write(void* handle, char* command, long timeout)
    >>> int read(void* handle, char** response, size_t buffersize, long timeout)
    >>>
    >>> Both return an error code, since the commands can fail for several
    >>> reasons that are not in the scope of the programmer (camera timeout,
    >>> camera not connected, ...).
    >>>
    >>> No I want to wrap this library. A member function of the camera shall
    >>> send a command to the camera and return it's response, e.g.
    >>>
    >>> std::string Camera::sendCommand(const std::string &command);
    >>>
    >>> My question: what is the best way to handle these errors:

    >>
    >> What exactly should happen when the camera is not connected or when a
    >> timeout occurs?

    >
    > On a timeout, I would like to try to send the command once more, maybe
    > write a log message, and inform the user. When the camera in not
    > connected, I would like to inform the usere immediately. Many differnt
    > approaches are possible. I haven't decides that yet.
    >
    >> For example, if there's just a message to be displayed to the user, then
    >> I don't see how the use of exceptions could possibly lead to all
    >> sendCommand calls being wrapped in try/catch blocks.

    >
    > The code to send the command for setting gain to a special value a
    > second time if it was not successfull the first time, might look like:
    >
    > try {
    > // send it the first time:
    > camera.sendCommand("set gain to value xyz");
    > }
    > catch(TimoutException)
    > {
    > // send it the second time:
    > camera.sendCommand("set gain to value xyz");
    > // don't catch the exception, if it fails twice
    > }
    >
    > Doesn't look very nice to me.

    That's because you're putting the logic in the wrong place...

    std::string Camera::sendCommand(const std::string &command, int
    maxRetries=1) {
    for (int retry = 0;;) {
    try {
    return doSendCommand(command);
    } catch(TimeoutException) {
    ++retry;
    if (retry >= maxRetries) {
    // Pardon me if the syntax is a little off,
    // I'm more frequently a Java programmer, and that's where I have
    // experience with exceptions.
    throw; // Rethrow the exception.
    }
    }
    }
    }


    Not the prettiest, but it is fully encapsulated in one place.

    BTW, I would suggest making that a private method, and adding public
    methods which wrap up the individual commands.

    void Camera::setGain(const Gain &gain) {
    sendCommand("set gain to value " + gain.asString());
    }

    Hope this helps.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, Jul 27, 2010
    #5
  6. Torsten

    Paul N Guest

    On 27 July, 10:26, Torsten <-hannover.de> wrote:
    > Hello,
    >
    > I'am currently wrapping a c-style library for using a camera and I am
    > not sure, how to handle errors.
    >
    > The API of the camera has functions for sending commands to the camera
    > and querying the cameras response from the camera:
    >
    > int write(void* handle, char* command, long timeout)
    > int read(void* handle, char** response, size_t buffersize, long timeout)
    >
    > Both return an error code, since the commands can fail for several
    > reasons that are not in the scope of the programmer (camera timeout,
    > camera not connected, ...).
    >
    > No I want to wrap this library. A member function of the camera shall
    > send a command to the camera and return it's response, e.g.
    >
    > std::string Camera::sendCommand(const std::string &command);
    >
    > My question: what is the best way to handle these errors:
    >
    > 1. Throw exceptions and wrap every sendCommand in a try/catch block?
    >     This makes the calling code quite ugly.
    > 2. Provide an error() function, that can be called after sending the
    >     command?
    > 3. Make the reponse an output parameter and return an error code?
    >     bool sendCommand(const std::string &command, std::string &response);
    >
    > Can someone give me an advice?


    One suggestion I have read is to write the calling code first. In the
    course of this you'll discover what you want the called code to do
    about errors.
     
    Paul N, Jul 27, 2010
    #6
  7. Torsten

    Torsten Guest

    Am 27.07.2010 23:27, schrieb Paul N:
    > On 27 July, 10:26, Torsten<-hannover.de> wrote:
    >> Hello,
    >>
    >> I'am currently wrapping a c-style library for using a camera and I am
    >> not sure, how to handle errors.
    >>
    >> The API of the camera has functions for sending commands to the camera
    >> and querying the cameras response from the camera:
    >>
    >> int write(void* handle, char* command, long timeout)
    >> int read(void* handle, char** response, size_t buffersize, long timeout)
    >>
    >> Both return an error code, since the commands can fail for several
    >> reasons that are not in the scope of the programmer (camera timeout,
    >> camera not connected, ...).
    >>
    >> No I want to wrap this library. A member function of the camera shall
    >> send a command to the camera and return it's response, e.g.
    >>
    >> std::string Camera::sendCommand(const std::string&command);
    >>
    >> My question: what is the best way to handle these errors:
    >>
    >> 1. Throw exceptions and wrap every sendCommand in a try/catch block?
    >> This makes the calling code quite ugly.
    >> 2. Provide an error() function, that can be called after sending the
    >> command?
    >> 3. Make the reponse an output parameter and return an error code?
    >> bool sendCommand(const std::string&command, std::string&response);
    >>
    >> Can someone give me an advice?

    >
    > One suggestion I have read is to write the calling code first. In the
    > course of this you'll discover what you want the called code to do
    > about errors.


    Good advice! Thank you. I'm going to write the calling code now. :)

    Torsten
     
    Torsten, Jul 28, 2010
    #7
  8. Torsten

    Torsten Guest

    Am 27.07.2010 20:28, schrieb Daniel Pitts:
    > On 7/27/2010 8:48 AM, Torsten wrote:
    >>>> [...]
    >>>>
    >>>> int write(void* handle, char* command, long timeout)
    >>>> int read(void* handle, char** response, size_t buffersize, long
    >>>> timeout)
    >>>>
    >>>> Both return an error code, since the commands can fail for several
    >>>> reasons that are not in the scope of the programmer (camera timeout,
    >>>> camera not connected, ...).
    >>>>
    >>>> No I want to wrap this library. A member function of the camera shall
    >>>> send a command to the camera and return it's response, e.g.
    >>>>
    >>>> std::string Camera::sendCommand(const std::string &command);
    >>>>
    >>>> My question: what is the best way to handle these errors:
    >>>
    >>> What exactly should happen when the camera is not connected or when a
    >>> timeout occurs?

    >>
    >> On a timeout, I would like to try to send the command once more, maybe
    >> write a log message, and inform the user. When the camera in not
    >> connected, I would like to inform the usere immediately. Many differnt
    >> approaches are possible. I haven't decides that yet.
    >>
    >>> For example, if there's just a message to be displayed to the user, then
    >>> I don't see how the use of exceptions could possibly lead to all
    >>> sendCommand calls being wrapped in try/catch blocks.

    >>
    >> The code to send the command for setting gain to a special value a
    >> second time if it was not successfull the first time, might look like:
    >>
    >> try {
    >> // send it the first time:
    >> camera.sendCommand("set gain to value xyz");
    >> }
    >> catch(TimoutException)
    >> {
    >> // send it the second time:
    >> camera.sendCommand("set gain to value xyz");
    >> // don't catch the exception, if it fails twice
    >> }
    >>
    >> Doesn't look very nice to me.

    > That's because you're putting the logic in the wrong place...
    >
    > std::string Camera::sendCommand(const std::string &command, int
    > maxRetries=1) {
    > for (int retry = 0;;) {
    > try {
    > return doSendCommand(command);
    > } catch(TimeoutException) {
    > ++retry;
    > if (retry >= maxRetries) {
    > // Pardon me if the syntax is a little off,
    > // I'm more frequently a Java programmer, and that's where I have
    > // experience with exceptions.
    > throw; // Rethrow the exception.
    > }
    > }
    > }
    > }
    >
    >
    > Not the prettiest, but it is fully encapsulated in one place.
    >
    > BTW, I would suggest making that a private method, and adding public
    > methods which wrap up the individual commands.
    >
    > void Camera::setGain(const Gain &gain) {
    > sendCommand("set gain to value " + gain.asString());


    Yes, that is actually what I do. I just tried to keep my posting short.

    I have an interface class Camera providing setGain(int gain) and similar
    methods, I have classes for 'real' cameras inheriting this interface and
    implementing the methoda via delegation to a CameraLinkCamera object
    that wraps the library:

    class Camera {
    public:
    virtual void setGain(int gain) const = 0;
    ...
    };

    class CameraE2v : public Camera {
    public:
    void setGain(int gain) const
    {
    camLinkCam->sendCommand(cmdString("CommandName", gain));
    }
    private:
    CameraLinkCamera *camLinkCam;
    };

    class CameraLinkCamera {
    public:
    void sendCommand(const std::string &cmd);
    private:
    ...
    };

    And only the CameraLinkCamera class generates exceptions. :)


    Thanks for your advice anyway. You all have been very helpfull.

    Torsten
     
    Torsten, Jul 28, 2010
    #8
  9. Torsten

    Jorgen Grahn Guest

    On Tue, 2010-07-27, Christian Hackl wrote:
    > Torsten ha scritto:
    >
    >> [...]
    >>
    >> int write(void* handle, char* command, long timeout)
    >> int read(void* handle, char** response, size_t buffersize, long timeout)
    >>
    >> Both return an error code, since the commands can fail for several
    >> reasons that are not in the scope of the programmer (camera timeout,
    >> camera not connected, ...).
    >>
    >> No I want to wrap this library. A member function of the camera shall
    >> send a command to the camera and return it's response, e.g.
    >>
    >> std::string Camera::sendCommand(const std::string &command);
    >>
    >> My question: what is the best way to handle these errors:

    >
    > What exactly should happen when the camera is not connected or when a
    > timeout occurs?
    >
    > For example, if there's just a message to be displayed to the user, then
    > I don't see how the use of exceptions could possibly lead to all
    > sendCommand calls being wrapped in try/catch blocks.
    >
    >
    > It seems that you are too quick to think in in low-level terms here.
    > Before deciding on how error handling should be implemented you should
    > decide on what the error handling should do.


    Which may be the same thing as deciding what "to wrap this library"
    means:
    - a general wrapper, released to the world
    - a wrapper used internally in your organization/by yourself
    - a single-purpose wrapper, used inside one particular application
    you're writing yourself.

    The last two are by far the easiest. You don't have to make policy
    decisions for other people.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jul 30, 2010
    #9
  10. Torsten

    Jorgen Grahn Guest

    On Tue, 2010-07-27, Torsten wrote:
    > On 27/07/10 17:17, Max wrote:
    >>> I'am currently wrapping a c-style library for using a camera and I
    >>> am not sure, how to handle errors.

    > >
    > > Why do you wrap it? Which problem are you trying to solve?

    >
    > Well, I want my application to support different types fo cameras, e.g.
    > CameraLink or GigE cameras. Therefore, I have to provide a common
    > interface for all types of cameras. The c-style library is acutally the
    > CameraLink library.


    Have a look at gPhoto (http://www.gphoto.org/). It seems to be what
    you want to do (except it wraps protocols, not other libraries, and I
    suppose it's a C API).

    If nothing else, you can see how they solved the common interface thing.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jul 30, 2010
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jason Coyne  Gaijin42

    Word wrap line break code and algorithm for c#

    Jason Coyne Gaijin42, Apr 8, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    24,371
    Jason Coyne Gaijin42
    Apr 8, 2004
  2. Aaron Fude

    To wrap or not to wrap?

    Aaron Fude, May 8, 2008, in forum: Java
    Replies:
    12
    Views:
    736
    Chronic Philharmonic
    May 10, 2008
  3. Guest
    Replies:
    0
    Views:
    480
    Guest
    Sep 14, 2005
  4. Art Werschulz

    Text::Wrap::wrap difference

    Art Werschulz, Sep 22, 2003, in forum: Perl Misc
    Replies:
    0
    Views:
    267
    Art Werschulz
    Sep 22, 2003
  5. Art Werschulz

    Text::Wrap::wrap difference

    Art Werschulz, Sep 24, 2003, in forum: Perl Misc
    Replies:
    1
    Views:
    273
    Anno Siegel
    Sep 25, 2003
Loading...

Share This Page