Re: Returning a string value from a c function to a Objective-C class method. Is there an approved approach?
Re: Returning a string value from a c function to a Objective-C class method. Is there an approved approach?
- Subject: Re: Returning a string value from a c function to a Objective-C class method. Is there an approved approach?
- From: Doug Hill <email@hidden>
- Date: Fri, 04 Mar 2016 18:17:09 -0800
Alex,
I guess I tried to make the distinction between Cocoa Bindings and language bindings, but I was referring to this.
https://en.wikipedia.org/wiki/Language_binding <https://en.wikipedia.org/wiki/Language_binding>
This is a general concept to bridge multiple languages.
The idea is that none of the bindings are automatic, you have to write them yourself. So, you would need to analyze the C library and figure out a set of interfaces in Objective-C that gives Obj-C developers access to that library.
Just as a hypothetical example (as I don’t have the knowledge or time to look up the SIP library you mentioned), let’s say the C library had the following functions:
SIPRef CreateSIPRef(void);
void DialNumber(SIPRef sipRef, char *phoneNumber);
Then your Objective-C interface would be something like:
@interface SIPDialer
@private
SIPRef privSIPRef;
- (instancetype) init;
- (void) dialNumber( NSString *phoneNumber);
@end
The implementation would do something like:
@implementation SIPDialer
- (instancetype) init
{
self = [super init];
if( self )
{
self.privSIPRef = CreateSIPRef();
}
return self;
}
- (void) dialNumber( NSString *phoneNumber)
{
char *cStrPhoneNumber = [phoneNumber cStringUsingEncoding: NSUTF8StringEncoding];
DialNumber( self.privSIPRef, cStrPhoneNumber);
}
@end
I think you get the general idea (ignore any typos or syntax errors, I’m just typing in my email here). Obviously you would also have to deal with all kinds of error handling and possibly exception handling.
Good luck!
Doug Hill
> On Mar 4, 2016, at 3:36 PM, Alex Zavatone <email@hidden> wrote:
>
> I guess I neglected to mention this was on iOS.
>
> Your words make me happy to see that I’m at least thinking along a similar line. Basically, your class is a glue layer or a translation layer between the C and Obj-C worlds.
>
> Now, I love the concept of bindings, but iOS, since bindings aren’t available, how would you suggest I approach the issue of the C method knowing the appropriate Obj-C class to provide the response to.
>
> I’m afraid I’ve been insulated from the world of pointers in my time on iOS, so I’m not rusty there, more than I am ignorant to those issues.
>
> Thanks,
>
> Alex Zavatone
>
> On Mar 4, 2016, at 5:11 PM, Doug Hill <email@hidden> wrote:
>
>> The approach I took for my wrapper library was using bindings. Not the Cocoa type, but the language type. I created a series of Objective-C classes that serve as the Obj-C interface to the Cocoa developer. The Obj-C classes would make calls into the C/C++ libraries and do conversions between C/C++ types to Obj-C. For example the C-string to NSString conversion. This way, a convenient Objective-C framework could be created that Cocoa developers could use very easily. C arrays were converted to Foundation NSArrays, etc. There was also conversions of C++ exceptions to Obj-C exceptions, although this might be unified in CLang/LLVM.
>> Since I was wrapping a C++ library, I made up some special bindings that allowed me to call into C++ objects via templates and some special sauce that allowed us to store method pointers and call into them from any platform/language. This is probably more work than is needed though.
>>
>> Anyways, I didn’t use delegates, notifications, etc. The easiest way to integrate these wrappers into your app is to have a pure Objective-C interface and do all work inside those, but probably the most effort to write.
>>
>> Doug Hill
>>
>>> On Mar 4, 2016, at 1:14 PM, Alex Zavatone <email@hidden> wrote:
>>>
>>> Great! It certainly does… but here's where my brain breaks.
>>>
>>> The call is originating from the C lib and within the C function. I am not calling the C function from Objective-C.
>>>
>>> I'm looking at somehow passing this as a string (UTF-8, yep) back to an OC class instance, so this implies either a callback or some reference to the OC instance that that cares about the response and a means to get that message to it.
>>>
>>> If this is as simple as setting up a callback or a pointer reference, from the c class to the OC instance? Is it sane programming for the C class to have more than one callback to different OC object instances?
>>>
>>> I was thinking one for data and one for method calls for organizational purposes.
>>>
>>> Or should there be one layer that serves as a clearly defined API to create a walled garden between the OC world and the C interface to the compiled C lib?
>>>
>>> I'm working with PJSIP and PJ's docs clearly state, "we are going to crater unless you do everything SIP related on the main thread." The code that I am rewriting replacing has nasty try/catch clauses and forces many operations to the main thread just in case they call PJSIP operations - which clearly makes for a sucky user experience and really clunky application architecture.
>>>
>>> I'm looking to avoid that nastiness by starting from ground zero so that we can wrap a solidly conceived architecture around a neatly walled off interface layer to PJSIP.
>>>
>>>
>>> Would it make sense to send a notification from the C method to an Objective-C object to get the value from the C class? Then I'd need to worry about storing it, that seems clunky and too involved just to return a string.
>>>
>>> Thank you, sir. Loads for me to learn here.
>>>
>>> Alex Zavatone
>>>
>>>
>>>
>>> On Mar 4, 2016, at 3:48 PM, Doug Hill wrote:
>>>
>>>> Alex,
>>>>
>>>> I’ve worked on a few wrapper libraries, so I have some experience with this.
>>>>
>>>> In your Obj-C wrapper, you would need to create the NSString yourself. So, if you have a C function:
>>>>
>>>> char* MyCFunc(void);
>>>>
>>>> The Objective-C wrapper method would do something like:
>>>>
>>>> - (void) myObjcMethod
>>>> {
>>>> char* cStr = MyCFunc();
>>>> NSString* objcStr = [[NSString alloc] initWithUTF8String:cStr];
>>>>
>>>> return objCStr;
>>>> }
>>>>
>>>> Depending on the C function implementation, you might have to deal with releasing the C string in your wrapper. Also, I assume UTF-8 encoding, which may or may not be true.
>>>>
>>>> Hopefully this helps you.
>>>>
>>>> Doug Hill
>>>>
>>>>
>>>>> On Mar 4, 2016, at 12:07 PM, Alex Zavatone <email@hidden> wrote:
>>>>>
>>>>> I'm in the middle of some fun where there is a wrapper class to a lib that's written in C and the c function has a char string that I'd like to return back to or somehow pass on to an Cbjective-C class.
>>>>>
>>>>> I'm sure there is an established practice for performing this type of task, but while I have the opportunity to do this, I'd like to start be learning the right way to handle this operation.
>>>>>
>>>>> I've seen really poor use of a catch all delegate for this approach, but am pretty unsure on viable and safe methods to handle this.
>>>>>
>>>>> Any tips to how to handle this?
>>>>>
>>>>> Thanks in advance,
>>>>>
>>>>> Alex Zavatone
>>>>
>>>>
>>>
>>
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden