How to properly wrap a C-Library

T

Torsten

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
 
A

Alf P. Steinbach /Usenet

* 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
 
T

Torsten

>
> 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
 
T

Torsten

[...]
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
 
D

Daniel Pitts

[...]

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.
 
P

Paul N

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.
 
T

Torsten

Am 27.07.2010 23:27, schrieb Paul N:
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
 
T

Torsten

Am 27.07.2010 20:28, schrieb Daniel Pitts:
[...]

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
 
J

Jorgen Grahn

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
 
J

Jorgen Grahn

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top