7

Okay, I've read half a dozen threads on this subject, but none of the solutions appear to address exact needs.

Question:

How does a Pure C (.c) function call a method inside a Pure Objective-C (.m) class?

Every example / answer is using C inside an Objective-C (.m) method. I have a Pure C library that I have to create a simulator for, so I need to keep my Kernel in pure C and call out to my higher level emulation methods in Objective-C.

Any attempt I make to create a reference and call a method fails. Square bracket notation fails as well. Creating a global var in Obj-C and trying to use that in Pure-C doesn't work, as if the namespace is segregated.

Anyone done this?

Here's a diagram of the flow:

Obj-C UIButton CLICKED->Calls Obj-C method->Calls C function->Call Obj-C method

Mark Löwe
  • 572
  • 1
  • 10
  • 24
  • 4
    `c` doesn't have class!!! – Anoop Vaidya Dec 06 '13 at 08:10
  • Sorry, typo. As in the title, I meant function. Thanks for the sighting the technicality. – Mark Löwe Dec 06 '13 at 08:12
  • Hi You can very well achieve your goal but you will have to have a merging point. You cant keep both separate and still work with both of them. create your test.c file import your test.c file in the required converge.m file you will have all the methods use this converge.m file to get result from c file and change it for consumption of objective-c. example – amar Dec 06 '13 at 08:27
  • Example for C++ is here (can be use with plain C, too): http://stackoverflow.com/questions/1061005/calling-objective-c-method-from-c-method) – avdyushin Dec 06 '13 at 08:29
  • use function pointer and mix of c and objectivec method in wrapper class – amar Dec 06 '13 at 08:35
  • change objective implementation class extension .m to .mm and include your c file in objective-C class and call directly your c method as you call in c. – Tirth Dec 06 '13 at 09:56
  • Is anything wrong with using `objc_msgSend` for this? [This question](http://stackoverflow.com/questions/2573805/using-objc-msgsend-to-call-a-objective-c-function-with-named-arguments) looks like a good example of this – Anya Shenanigans Dec 06 '13 at 10:52

3 Answers3

3

After much experimenting, I found that the most elegant way of solving my problem was to turn my core C library into an NSObject using the .m suffix. The method of calling back and forth resolved instantly. This change DOES alter my original library, but by so little, it's manageable. So to review:

My original C file was renamed to use the .m suffix. Then I added

@interface myCLibrary : NSObject

@end

to my .h file, and added to my formerly .c file, now renamed .m.

@implementation myCLibrary

@end

Just remember that C functions aren't to be pasted between these interface / implementation declarations, below them. Only Objective-C is to go inside these statements. Once I did that, calling the C functions, and calling BACK to other C functions worked great.

Thanks for all the help regardless.

Mark Löwe
  • 572
  • 1
  • 10
  • 24
1

Objective C can compile c method without any modification. To call c method from objective-c class you have to whatever you do in c, just include the header file then call method directly. Suppose you have a C header named test.h and in that you have a method sum(int i, int j); then first include test.h and then call test(1, 2);

If you want to call C++ method, use Objective-C++ (.mm extension) in the same manner as explained above.

doptimusprime
  • 9,115
  • 6
  • 52
  • 90
Abdullah Md. Zubair
  • 3,312
  • 2
  • 30
  • 39
  • One correction: Only C, not C++. Objective-C++ can call C++ method. – doptimusprime Dec 06 '13 at 08:31
  • You know I tried this, and I get an error of "implicit declaration of function "test" is invalid in C99. I'm using GNU99 though. I guess C99 is used for the C side of the linking? – Mark Löwe Dec 06 '13 at 08:40
  • to avoid error on C99 you can follow this: http://stackoverflow.com/questions/15850042/warning-implicit-declaration-of-function-is-invalid-in-c99 – Abdullah Md. Zubair Dec 06 '13 at 08:43
  • The challenge with those solutions is that the test method IS declared in the imported view controller, so declaring it again would probably throw the compiler off in thinking that it belongs to somewhere else. – Mark Löwe Dec 06 '13 at 08:44
  • you can create a .h file then you can declare your c method on the file. then you can include the .h file, I think this will solve your problem. – Abdullah Md. Zubair Dec 06 '13 at 09:10
  • Actually, including an ObjC header inside a C file broke the compiler. The ObjC file being included can no longer resolve UIKit. – Mark Löwe Dec 06 '13 at 10:17
  • Actually, I was saying to create create header file for C and it should be on C language. You can follow this link on creation header file on C language: http://stackoverflow.com/questions/2831361/how-can-i-create-c-header-files – Abdullah Md. Zubair Dec 06 '13 at 10:39
0

I hope i understand you correctly!

You can do this via callback-function.

In you C file use this:

Define the callback-type

eventcallback g_callback;

Implement callback-class (executed by objective-c code)

void comm_set_callback(eventcallback callback){
   g_callback = callback;
}

in objective-c:

Set the callback (i.e.: in viewDidLoad())

comm_set_callback(&testfkt);

C-Method called from extern C-function

void testfkt(){
 [refToSelf testmethod];
}

Objective-C Method called from C-Method testfkt

-(void)testmethod{
   ...
}
nirvana002
  • 75
  • 1
  • 7
  • I like where you're going, but where does "eventcallback" type come from? I'm getting an error. – Mark Löwe Dec 06 '13 at 08:41
  • @MarkLöwe Don't substitute mechanically. Those are metasyntactic types. You'll have to change them to actual types defined by you. –  Dec 06 '13 at 08:43
  • I guess I'm asking, is that a function reference? – Mark Löwe Dec 06 '13 at 08:49
  • use this in your .h file typedef void (*eventcallback)(void); – nirvana002 Dec 06 '13 at 08:50
  • Did you mean "&testmethod" in this line? comm_set_callback(&testfkt); – Mark Löwe Dec 06 '13 at 09:07
  • no, testmethod is the objective-c method called from the c-function in the objective-c .m file. you can call the objective-c method from the c-file with: (*g_callback)(); – nirvana002 Dec 06 '13 at 09:09
  • So how do I send the function from ObjC &test to my C function? (BTW, all the sudden my UIKit isn't resolving for my ViewController, works fine for other classes, but all the sudden fails during editing, ARG). My understand as that during the viewDidLoad method, I send a &ref of my method to the C-function for later recalling. – Mark Löwe Dec 06 '13 at 09:17
  • yes you're right. you call the comm_set_callback-method and after that you have the callback in your c-class. there you execute (*g_callback)(); i mentioned that all before... – nirvana002 Dec 06 '13 at 09:20
  • Well I understand your theory quite well, but your code does NOT account for the communication that needs to take place. ObjC HAS to send a pointer to ITS "method" to the C code that is stored in the function reference, and that isn't happening. But I get it. It remains a subject that no one can describe with any intelligence. – Mark Löwe Dec 06 '13 at 09:30
  • Why you don't understand that: comm_set_callback sends &testfkt to the c-function which is the address of your c-function in the .m file. via this you can call testfkt() in your c-file and you will get back to the c-function in the .m file. now you can use a reference to self (defined globally) to access any objective-c method you want. – nirvana002 Dec 06 '13 at 09:36
  • The compiler won't allow the &testfkt line. Claims an implicit declaration error. :( I'll have this figured out the second I can figure out how to send a method pointer to the C function pointer. &syntax is failing. – Mark Löwe Dec 06 '13 at 10:25
  • have you declared void comm_set_callback(eventcallback callback); and imported your .h file in objective-c? – nirvana002 Dec 06 '13 at 10:29
  • Make sure you've seen the flow I added above to understand the chain of events. OC->C->OC. So C needs to store the pointer back to OC. – Mark Löwe Dec 06 '13 at 10:33
  • my example is the solution of your chain. i tested it on my own and everything works fine. my last try to explain it: 1. obj-c: set callback in viewDidLoad 2. obj-c: call your c-method on UIButton clicked 3. c: do something in your method 4. c: call callback-method from point 1 5. obj-c: call an obj-c method via global stored self – nirvana002 Dec 06 '13 at 12:11
  • Perhaps you can edit your five gray code samples above to help me understand. I have TWO files ViewController.m, Callback.c. It appears you're telling me the first two gray blocks go in Callback.c. The third gray block goes in ViewController.m...however Xcode will not allow a &ref to any of my Obj-C methods. The four block appears to go in Callback.c, HOWEVER [] notion isn't allowed, so fail there. The last block is entirely orphaned in the example. You mention "testmethod" but I don't see it defined everywhere. – Mark Löwe Dec 07 '13 at 12:03
  • It's probably best to pretend that anything left out or implied leaves me at the point I posted the question. I'm lost with this entire thing. I feel like a pointer to a function should have been the ONLY thing necessary to get this working, and I'm baffled that the entire development community never does this without some titanic amount of ugly code. – Mark Löwe Dec 07 '13 at 12:03
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42702/discussion-between-mark-lowe-and-nirvana002) – Mark Löwe Dec 07 '13 at 12:17