Wrapping C functions in Objective C proxy objects: naming convention?
-
For a project that I'm working on, I have a need to write a code
generator that will wrap certain kinds of C functions as Objective C
messages on an Objective C proxy. Because I don't ultimately control
the input, the parameters on the C functions may be poorly named. I'm
looking for advice on how one might make useful object message names
from C functions.
The format of the functions in question is essentially like this[1]:
int ns__add(double a, double b, double *result);
int ns__sub(double a, double b, double *result);
int ns__mul(double a, double b, double *result);
int ns__div(double a, double b, double *result);
int ns__pow(double a, double b, double *result);
The int return is a status code; the result of the operation is in
double* result. If there's an error in the operation. (The status code
may be ignorable, in which case part of my following question is
answered; I'm still researching this part. I suspect that it is best
not ignored.)
Anyway, the problem is how I should convert this function with poorly
named parameters into a proxy object and messages?
The options that I've come up with (expressed in terms of use) follow.
They're all expressed in terms of an object ns__CalcProxy:
ns__CalcProxy calc = [[ns__CalcProxy alloc] init];
double a, b, result;
int status;
result = [calc addDoubleA:a withDoubleB:b]; // #1
result = [calc addDoubleA:a withDoubleB:b status:&status]; // #2
status = [calc addDoubleA:a withDoubleB:b returning:&result]; // #3
The examples given here are simple; the items being returned may in
fact be pretty complex (and I'm planning on making it so that
structured parameters and return values may be passed in Objective C
proxies themselves).
I really don't like the "addDoubleA:withDoubleB:" name, to be honest,
but what am I supposed to do with:
struct ns1__ludcmpResponse {matrix *a; ivector *i; xsd__double d;};
int ns1__ludcmp(matrix *a, struct ns1__ludcmpResponse** result);
Like I said; I don't really have any control over the names of the
parameters, more's the pity.
-austin
[1] Actually, they're more like this:
int soap_call_ns__add(struct soap *soap, const char *soap_endpoint,
const char *soap_action, double a, double b, double *result);
But there's enough information in there for me to extract the former
to use as a proxy function.
--
Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
* <austin...> * http://www.halostatue.ca/feed/
* <austin...> -
Austin,
I’d go for #1.
If you have an error in status, throw an exception.
What is the reason to put those functions in a class anyway if you
just mimic the c-function? Are you adding anything?
atze
Am 20.11.2008 um 06:27 schrieb Austin Ziegler:
> For a project that I'm working on, I have a need to write a code
> generator that will wrap certain kinds of C functions as Objective C
> messages on an Objective C proxy. Because I don't ultimately control
> the input, the parameters on the C functions may be poorly named. I'm
> looking for advice on how one might make useful object message names
> from C functions.
>
> The format of the functions in question is essentially like this[1]:
>
> int ns__add(double a, double b, double *result);
> int ns__sub(double a, double b, double *result);
> int ns__mul(double a, double b, double *result);
> int ns__div(double a, double b, double *result);
> int ns__pow(double a, double b, double *result);
>
> The int return is a status code; the result of the operation is in
> double* result. If there's an error in the operation. (The status code
> may be ignorable, in which case part of my following question is
> answered; I'm still researching this part. I suspect that it is best
> not ignored.)
>
> Anyway, the problem is how I should convert this function with poorly
> named parameters into a proxy object and messages?
>
> The options that I've come up with (expressed in terms of use) follow.
> They're all expressed in terms of an object ns__CalcProxy:
>
> ns__CalcProxy calc = [[ns__CalcProxy alloc] init];
> double a, b, result;
> int status;
>
> result = [calc addDoubleA:a withDoubleB:b]; // #1
> result = [calc addDoubleA:a withDoubleB:b status:&status]; // #2
> status = [calc addDoubleA:a withDoubleB:b returning:&result]; // #3
>
> The examples given here are simple; the items being returned may in
> fact be pretty complex (and I'm planning on making it so that
> structured parameters and return values may be passed in Objective C
> proxies themselves).
>
> I really don't like the "addDoubleA:withDoubleB:" name, to be honest,
> but what am I supposed to do with:
>
> struct ns1__ludcmpResponse {matrix *a; ivector *i; xsd__double d;};
> int ns1__ludcmp(matrix *a, struct ns1__ludcmpResponse** result);
>
> Like I said; I don't really have any control over the names of the
> parameters, more's the pity.
>
> -austin
> [1] Actually, they're more like this:
> int soap_call_ns__add(struct soap *soap, const char *soap_endpoint,
> const char *soap_action, double a, double b, double *result);
> But there's enough information in there for me to extract the former
> to use as a proxy function.
> --
> Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
> * <austin...> * http://www.halostatue.ca/feed/
> * <austin...>
---
Alexander Spohr
Freeport & Soliversum
Fax: +49 40 303 757 99
Web: http://www.freeport.de/
Box: http://dropbox.letsfile.com/02145299-4347-4671-aab9-1d3004eac51d
--- -
On Thu, Nov 20, 2008 at 4:54 AM, Alexander Spohr <atze...> wrote:
> I'd go for #1.
> If you have an error in status, throw an exception.
>
> What is the reason to put those functions in a class anyway if you just
> mimic the c-function? Are you adding anything?
Yes, I am. The C function definition that I showed was actually just a
SOAP service definition. What my proxy object will be calling are
about three or four different C functions to make the SOAP call,
hiding that complexity from the programmer. (I could just use C++ and
have this code generated for me automatically, but this is also an
intellectual challenge to generate these Objective C wrappers that
mimic what the C++ code does.)
-austin
> Am 20.11.2008 um 06:27 schrieb Austin Ziegler:
>> For a project that I'm working on, I have a need to write a code
>> generator that will wrap certain kinds of C functions as Objective C
>> messages on an Objective C proxy. Because I don't ultimately control
>> the input, the parameters on the C functions may be poorly named. I'm
>> looking for advice on how one might make useful object message names
>> from C functions.
>>
>> The format of the functions in question is essentially like this[1]:
>>
>> int ns__add(double a, double b, double *result);
>> int ns__sub(double a, double b, double *result);
>> int ns__mul(double a, double b, double *result);
>> int ns__div(double a, double b, double *result);
>> int ns__pow(double a, double b, double *result);
>>
>> The int return is a status code; the result of the operation is in
>> double* result. If there's an error in the operation. (The status code
>> may be ignorable, in which case part of my following question is
>> answered; I'm still researching this part. I suspect that it is best
>> not ignored.)
>>
>> Anyway, the problem is how I should convert this function with poorly
>> named parameters into a proxy object and messages?
>>
>> The options that I've come up with (expressed in terms of use) follow.
>> They're all expressed in terms of an object ns__CalcProxy:
>>
>> ns__CalcProxy calc = [[ns__CalcProxy alloc] init];
>> double a, b, result;
>> int status;
>>
>> result = [calc addDoubleA:a withDoubleB:b]; // #1
>> result = [calc addDoubleA:a withDoubleB:b status:&status]; // #2
>> status = [calc addDoubleA:a withDoubleB:b returning:&result]; // #3
>>
>> The examples given here are simple; the items being returned may in
>> fact be pretty complex (and I'm planning on making it so that
>> structured parameters and return values may be passed in Objective C
>> proxies themselves).
>>
>> I really don't like the "addDoubleA:withDoubleB:" name, to be honest,
>> but what am I supposed to do with:
>>
>> struct ns1__ludcmpResponse {matrix *a; ivector *i; xsd__double d;};
>> int ns1__ludcmp(matrix *a, struct ns1__ludcmpResponse** result);
>>
>> Like I said; I don't really have any control over the names of the
>> parameters, more's the pity.
>>
>> -austin
>> [1] Actually, they're more like this:
>> int soap_call_ns__add(struct soap *soap, const char *soap_endpoint,
>> const char *soap_action, double a, double b, double *result);
>> But there's enough information in there for me to extract the former
>> to use as a proxy function.
>> --
>> Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
>> * <austin...> * http://www.halostatue.ca/feed/
>> * <austin...>
>
> ---
> Alexander Spohr
> Freeport & Soliversum
>
> Fax: +49 40 303 757 99
> Web: http://www.freeport.de/
> Box: http://dropbox.letsfile.com/02145299-4347-4671-aab9-1d3004eac51d
> ---
>
>
>
>
--
Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
* <austin...> * http://www.halostatue.ca/feed/
* <austin...> -
On Nov 20, 2008, at 6:58 AM, Austin Ziegler wrote:
>>> result = [calc addDoubleA:a withDoubleB:b]; // #1
Why not -addDouble:withDouble: ?
That is, why are you promoting the argument names into the method
signature? Especially since you're aware that the names are (most
often) useless.
>>> result = [calc addDoubleA:a withDoubleB:b status:&status]; // #2
>>> status = [calc addDoubleA:a withDoubleB:b returning:&result]; // #3
These forms might also make sense, but I'd still leave out the 'A' and
'B'. I believe that Apple's naming conventions suggest that, when a
method outputs multiple values, they should all be output parameters
and none should be via return value. Also, Apple has been migrating
towards using NSError objects output via parameter to handle status.
So, you might want to do the same.
http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/
Articles/NamingMethods.html
Cheers,
Ken -
On Nov 20, 2008, at 10:54 AM, Alexander Spohr wrote:
> I’d go for #1.
> If you have an error in status, throw an exception.
In this case, an exception might actually be OK, given that the
library is in isolation.
However, it goes against the design patterns of Cocoa and if the code
is ever refactored such that there are Foundation or AppKit frames on
the stack over which the exception is thrown, the code may break.
Exceptions for non-programmer error are to be avoided.
b.bum -
On Thu, Nov 20, 2008 at 12:27 AM, Austin Ziegler <halostatue...> wrote:
> For a project that I'm working on, I have a need to write a code
> generator that will wrap certain kinds of C functions as Objective C
> messages on an Objective C proxy. Because I don't ultimately control
> the input, the parameters on the C functions may be poorly named. I'm
> looking for advice on how one might make useful object message names
> from C functions.
>
> The format of the functions in question is essentially like this[1]:
>
> int ns__add(double a, double b, double *result);
> int ns__sub(double a, double b, double *result);
> int ns__mul(double a, double b, double *result);
> int ns__div(double a, double b, double *result);
> int ns__pow(double a, double b, double *result);
>
> The int return is a status code; the result of the operation is in
> double* result. If there's an error in the operation. (The status code
> may be ignorable, in which case part of my following question is
> answered; I'm still researching this part. I suspect that it is best
> not ignored.)
>
> Anyway, the problem is how I should convert this function with poorly
> named parameters into a proxy object and messages?
>
> The options that I've come up with (expressed in terms of use) follow.
> They're all expressed in terms of an object ns__CalcProxy:
>
> ns__CalcProxy calc = [[ns__CalcProxy alloc] init];
> double a, b, result;
> int status;
>
> result = [calc addDoubleA:a withDoubleB:b]; // #1
> result = [calc addDoubleA:a withDoubleB:b status:&status]; // #2
> status = [calc addDoubleA:a withDoubleB:b returning:&result]; // #3
Please excuse a foolish question, but.... Why wrap this in Objective-C
at all? Looks like the resulting ObjC code is essentially the same,
except uglier, slower, and harder to use. Why not just keep the C and
use it directly?
Mike -
On Thu, Nov 20, 2008 at 12:15 PM, Michael Ash <michael.ash...> wrote:
> Please excuse a foolish question, but.... Why wrap this in Objective-C
> at all? Looks like the resulting ObjC code is essentially the same,
> except uglier, slower, and harder to use. Why not just keep the C and
> use it directly?
This isn't a foolish question. The function declaration that I've shown
you is something of a fiction; it's a definition in an input file to a
code generator (gSOAP). It doesn't actually exist in the resulting C
code. This definition:
>> int ns__add(double a, double b, double *result);
will actually become:
int soap_call_ns__add(struct soap *soap, const char *endpoint,
const char *action, double a, double b,
double result*);
gSOAP knows how to generate C and C++ and with C++ will generate a proxy
for this C function and the SOAP object, so that it looks more like:
class calcProxy
{
public:
int add(double a, double b, double *result)
{
return soap_call_ns__add(soap, endpoint, "", a, b, result);
}
struct soap *soap;
char *endpoint;
}
What I want to do is to create an ObjC proxy similar to the C++ proxy.
Yes, I know I could use ObjC++, but there are reasons I want to use ObjC
instead of ObjC++ including not having to deal with two different object
models in my ObjC programs.
Generating the proxy isn't going to be that hard; I'm just trying to
figure out what the best naming conventions for these generated methods
and classes will be.
-austin
--
Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
* <austin...> * http://www.halostatue.ca/feed/
* <austin...> -
On Nov 19, 2008, at 9:27 PM, Austin Ziegler wrote:
> For a project that I'm working on, I have a need to write a code
> generator that will wrap certain kinds of C functions as Objective C
> messages on an Objective C proxy. Because I don't ultimately control
> the input, the parameters on the C functions may be poorly named. I'm
> looking for advice on how one might make useful object message names
> from C functions.
Just my 2 cents, but it seems an abuse to turn functions into objects.
Functions don't retain state; objects do. Objective C very gracefully
allows objects to call C functions. If you're doing something like
[calc addDoubleA:a withDoubleB:b], you've got a function masquerading
as an object, which I think misses the entire point of OOP. -
On Thu, Nov 20, 2008 at 1:23 PM, Jonathon Kuo
<newslists...> wrote:
> Just my 2 cents, but it seems an abuse to turn functions into objects.
> Functions don't retain state; objects do. Objective C very gracefully allows
> objects to call C functions. If you're doing something like [calc
> addDoubleA:a withDoubleB:b], you've got a function masquerading as an
> object, which I think misses the entire point of OOP.
It is common, if not appropriate, to have utility classes (often ones
with just class methods) that provide "functions" for others to use.
At a minimum it allows you to namespace sets of utility methods.
-Shawn -
Just out of curiosity, why do you need to send such common math
operations to a soap request? Wouldn't it be easier to do simple stuff
like calculations in your Soap class and only make requests for the
unique services the endpoint provides?
On Nov 20, 2008, at 12:27 AM, Austin Ziegler wrote:
> For a project that I'm working on, I have a need to write a code
> generator that will wrap certain kinds of C functions as Objective C
> messages on an Objective C proxy. Because I don't ultimately control
> the input, the parameters on the C functions may be poorly named. I'm
> looking for advice on how one might make useful object message names
> from C functions.
>
> The format of the functions in question is essentially like this[1]:
>
> int ns__add(double a, double b, double *result);
> int ns__sub(double a, double b, double *result);
> int ns__mul(double a, double b, double *result);
> int ns__div(double a, double b, double *result);
> int ns__pow(double a, double b, double *result);
>
> The int return is a status code; the result of the operation is in
> double* result. If there's an error in the operation. (The status code
> may be ignorable, in which case part of my following question is
> answered; I'm still researching this part. I suspect that it is best
> not ignored.)
>
> Anyway, the problem is how I should convert this function with poorly
> named parameters into a proxy object and messages?
>
> The options that I've come up with (expressed in terms of use) follow.
> They're all expressed in terms of an object ns__CalcProxy:
>
> ns__CalcProxy calc = [[ns__CalcProxy alloc] init];
> double a, b, result;
> int status;
>
> result = [calc addDoubleA:a withDoubleB:b]; // #1
> result = [calc addDoubleA:a withDoubleB:b status:&status]; // #2
> status = [calc addDoubleA:a withDoubleB:b returning:&result]; // #3
>
> The examples given here are simple; the items being returned may in
> fact be pretty complex (and I'm planning on making it so that
> structured parameters and return values may be passed in Objective C
> proxies themselves).
>
> I really don't like the "addDoubleA:withDoubleB:" name, to be honest,
> but what am I supposed to do with:
>
> struct ns1__ludcmpResponse {matrix *a; ivector *i; xsd__double d;};
> int ns1__ludcmp(matrix *a, struct ns1__ludcmpResponse** result);
>
> Like I said; I don't really have any control over the names of the
> parameters, more's the pity.
>
> -austin
> [1] Actually, they're more like this:
> int soap_call_ns__add(struct soap *soap, const char *soap_endpoint,
> const char *soap_action, double a, double b, double *result);
> But there's enough information in there for me to extract the former
> to use as a proxy function.
> --
> Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
> * <austin...> * http://www.halostatue.ca/feed/
> * <austin...>
-
On Nov 20, 2008, at 2:07 PM, Shawn Erickson wrote:
> On Thu, Nov 20, 2008 at 1:23 PM, Jonathon Kuo
> <newslists...> wrote:
>
>> Just my 2 cents, but it seems an abuse to turn functions into
>> objects.
>> Functions don't retain state; objects do. Objective C very
>> gracefully allows
>> objects to call C functions. If you're doing something like [calc
>> addDoubleA:a withDoubleB:b], you've got a function masquerading as an
>> object, which I think misses the entire point of OOP.
>
> It is common, if not appropriate, to have utility classes (often ones
> with just class methods) that provide "functions" for others to use.
> At a minimum it allows you to namespace sets of utility methods.
Exactly, as classes aren't objects. -
On Nov 20, 2008, at 5:58 PM, Jonathon Kuo wrote:
> On Nov 20, 2008, at 2:07 PM, Shawn Erickson wrote:
>
>> On Thu, Nov 20, 2008 at 1:23 PM, Jonathon Kuo
>> <newslists...> wrote:
>>
>>> Just my 2 cents, but it seems an abuse to turn functions into
>>> objects.
>>> Functions don't retain state; objects do. Objective C very
>>> gracefully allows
>>> objects to call C functions. If you're doing something like [calc
>>> addDoubleA:a withDoubleB:b], you've got a function masquerading as
>>> an
>>> object, which I think misses the entire point of OOP.
>>
>> It is common, if not appropriate, to have utility classes (often ones
>> with just class methods) that provide "functions" for others to use.
>> At a minimum it allows you to namespace sets of utility methods.
>
> Exactly, as classes aren't objects.
Yes they are - in Objective-C, anyway.
Charles -
On Nov 20, 2008, at 5:06 PM, Charles Srstka wrote:
> On Nov 20, 2008, at 5:58 PM, Jonathon Kuo wrote:Oops, my bad. Meant to say classes aren't instantiated objects (and
>
>> On Nov 20, 2008, at 2:07 PM, Shawn Erickson wrote:
>>
>>> On Thu, Nov 20, 2008 at 1:23 PM, Jonathon Kuo
>>> <newslists...> wrote:
>>>
>>>> Just my 2 cents, but it seems an abuse to turn functions into
>>>> objects.
>>>> Functions don't retain state; objects do. Objective C very
>>>> gracefully allows
>>>> objects to call C functions. If you're doing something like [calc
>>>> addDoubleA:a withDoubleB:b], you've got a function masquerading
>>>> as an
>>>> object, which I think misses the entire point of OOP.
>>>
>>> It is common, if not appropriate, to have utility classes (often
>>> ones
>>> with just class methods) that provide "functions" for others to use.
>>> At a minimum it allows you to namespace sets of utility methods.
>>
>> Exactly, as classes aren't objects.
>
> Yes they are - in Objective-C, anyway.
>
thus they have no context or state, and so are appropriate for library-
type functions, etc.) -
On Nov 20, 2008, at 7:40 PM, Jonathon Kuo wrote:
>
> On Nov 20, 2008, at 5:06 PM, Charles Srstka wrote:
>
>> On Nov 20, 2008, at 5:58 PM, Jonathon Kuo wrote:
>>
>>> On Nov 20, 2008, at 2:07 PM, Shawn Erickson wrote:
>>>
>>>> On Thu, Nov 20, 2008 at 1:23 PM, Jonathon Kuo
>>>> <newslists...> wrote:
>>>>
>>>>> Just my 2 cents, but it seems an abuse to turn functions into
>>>>> objects.
>>>>> Functions don't retain state; objects do. Objective C very
>>>>> gracefully allows
>>>>> objects to call C functions. If you're doing something like [calc
>>>>> addDoubleA:a withDoubleB:b], you've got a function masquerading
>>>>> as an
>>>>> object, which I think misses the entire point of OOP.
>>>>
>>>> It is common, if not appropriate, to have utility classes (often
>>>> ones
>>>> with just class methods) that provide "functions" for others to
>>>> use.
>>>> At a minimum it allows you to namespace sets of utility methods.
>>>
>>> Exactly, as classes aren't objects.
>>
>> Yes they are - in Objective-C, anyway.
>>
> Oops, my bad. Meant to say classes aren't instantiated objects (and
> thus they have no context or state, and so are appropriate for
> library-type functions, etc.)
Yep. Good thing the built-in Cocoa frameworks don't have any
instantiated objects that contain library-type functions. Otherwise,
we'd have all sorts of singleton objects with names like
NSFileManager, NSWorkspace, NSUserDefaults, NSFontManager...
Charles -
On Nov 20, 2008, at 5:53 PM, Charles Srstka wrote:
> On Nov 20, 2008, at 7:40 PM, Jonathon Kuo wrote:Well, to be fair, in each class you mention, you're accessing a
>
>>
>> On Nov 20, 2008, at 5:06 PM, Charles Srstka wrote:
>>
>>> On Nov 20, 2008, at 5:58 PM, Jonathon Kuo wrote:
>>>
>>>> On Nov 20, 2008, at 2:07 PM, Shawn Erickson wrote:
>>>>
>>>>> On Thu, Nov 20, 2008 at 1:23 PM, Jonathon Kuo
>>>>> <newslists...> wrote:
>>>>>
>>>>>> Just my 2 cents, but it seems an abuse to turn functions into
>>>>>> objects.
>>>>>> Functions don't retain state; objects do. Objective C very
>>>>>> gracefully allows
>>>>>> objects to call C functions. If you're doing something like [calc
>>>>>> addDoubleA:a withDoubleB:b], you've got a function masquerading
>>>>>> as an
>>>>>> object, which I think misses the entire point of OOP.
>>>>>
>>>>> It is common, if not appropriate, to have utility classes (often
>>>>> ones
>>>>> with just class methods) that provide "functions" for others to
>>>>> use.
>>>>> At a minimum it allows you to namespace sets of utility methods.
>>>>
>>>> Exactly, as classes aren't objects.
>>>
>>> Yes they are - in Objective-C, anyway.
>>>
>> Oops, my bad. Meant to say classes aren't instantiated objects (and
>> thus they have no context or state, and so are appropriate for
>> library-type functions, etc.)
>
> Yep. Good thing the built-in Cocoa frameworks don't have any
> instantiated objects that contain library-type functions. Otherwise,
> we'd have all sorts of singleton objects with names like
> NSFileManager, NSWorkspace, NSUserDefaults, NSFontManager...
>
special object: the default NSFileManager object for the file system,
the shared NSWorkspace instance, etc. Those aren't examples of simple
libraries in class clothing, which is all I was getting at. -
On Thu, Nov 20, 2008 at 6:09 PM, Ken Tozier <kentozier...>
wrote:
> Just out of curiosity, why do you need to send such common math
> operations to a soap request? Wouldn't it be easier to do simple stuff
> like calculations in your Soap class and only make requests for the
> unique services the endpoint provides?
What I presented here was sample code that's fed to the gSOAP generator
(soapcpp2). What I'm writing is a further generator that will generate
an Objective C proxy on top of the gSOAP service.
I personally don't ever need to do add, sub, mul, div, or pow. However,
looking at how SOAP clients and servers are implemented using these
simple examples is instructive.
Trust me; the stuff I am *really* doing is a few orders harder than
simple math operations. But as you're doing something new, it's always
smart to take baby steps.
-austin
--
Austin Ziegler * <halostatue...> * http://www.halostatue.ca/
* <austin...> * http://www.halostatue.ca/feed/
* <austin...>



