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
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.
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.
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{
...
}
Related
My App is objective-c origin, with all new files being Swift. My main.m file has:
ConfigMgr* configMgr;
All my objective-c (.m) files have:
extern ConfigMgr* configMgr;
It's a global pointer because everyone needs to access some info about the configuration. (It's my only global and I make no apology for it.) So what do I add to my Swift files to be able to access this instance of this object as well, by using the global, not passing a pointer to every .swift file? (My main concern is to make sure I don't end up instantiating another ConfigMgr object.)
Assuming that the interface of the ConfigMgr class is declared in ConfigMgr.h, include the following in the bridging header:
#import "ConfigMgr.h"
extern ConfigMgr* configMgr;
You should be good to go!
I am using a static library built by someone else in my Objective-C project. There is a C method in the library that I want to call, but it is not exported. How can a call this method from Objective-C code?
First of all: Why do you need that? Obviously the author of that framework did not see any need for this and things can break, if a method is executed directly.
However: Write a category on the receiver with that method and just do it. Objective-C binds dynamically, so this works.
#interface FrameworkClass(InternalMethodAddition)
- (void)internalMethod;
#end
// Do not implement this category.
…
FrameworkClass *object = …
[object internalMethod];
When writing an iOS app, where would I place a function that I intend to use from any other file?
For example, a function to convert a NSDate to a relative time string ("5 secs ago").
Would I make a class and make these functions all static?
Functions can be placed wherever convenient. If a function or group of functions is likely to be imported in many places, you can declare and implement them in their own .h/.m pair. So for example you might implement your date conversion function in a file named XYZDateUtilities.m, and declare it in XYZDateUtilities.h.
Declaring functions with the static qualifier would limit their scope to the file in which they were declared, so you wouldn't want to do that; in fact you'd want to do the opposite -- declare them as extern in the .h file so that they'll be visible in other files.
You have a couple options:
1) If you're extending the behavior of a class (such as the NSDate string conversion method you described), it may work best to simply create a category on said class.
Here's a tutorial on iOS categories:
http://mobile.tutsplus.com/tutorials/iphone/objective-c-categories/
Important Note:
Categories change a class's behavior (if you override a method) everywhere within the project whether or not you include the header (.h) file in another specific class's imports
For this reason, it's generally best to not override methods via a category, but instead, to create a subclass if you want to change certain methods.
For adding new methods, however, categories can be very convenient and useful.
2) If you want to create a new class that's imported everywhere, you can create said class and put its header import, i.e. #import "MyClass.h", into your project's prefix.pch file (found under the "supporting files" group within the project by default).
Anything that you put into the prefix.pch file will be available anywhere within your app. This is also a useful place to put constants (such as strings) or define enums that are used across many classes within the app.
I hope this helps. Let me know if further clarification is needed, and I'll do my best to help.
Cheers!
Another option would be to create a class for your helper methods and implement all the helpers as class methods.
e.g. HelperClass.h
+ (NSString *)getFrenchCapital
e.g. HelperClass.m
+ (NSString *)getFrenchCapital
{
return #"Paris";
}
Then import your helper class wherever you need it, and simply call the class methods:
e.g. Foo.m
#import "HelperClass.h"
...
- (void)logFrenchCapital
{
NSLog(#"Capital of France: %#", [HelperClass getFrenchCapital]);
}
If you make all functions static in a class, then alternative is to just define functions in .m file, and extern functions in .h file, just like what you do in C.
My obj-c class uses a C library (the Chipmunk physics engine), which has an Obj-C wrapper interface.
I want to add a property with a chipmunk type (cpLayers) to my object, like so:
#interface
#property cpLayers layers;
...
The easiest way is to #import "ObjectiveChipmunk.h", but that seems ridiculous to import all of the headers just to get one measly type.
If I #import the C "chipmunk_types.h" file where cpLayers is defined "typedef unsigned int cpLayers;", I get compiler errors related to ARC. They are bridge/casting errors in a macro that is defined in chipmunk_types.h and used in my .m file.
If I add just the definition, or #include chipmunk_types.h, I get redefinition errors.
Is there any better way to do this? And WHY the ARC errors?
Take a look at the ObjectiveChipmunk.h, that is where it overrides the basic Chipmunk types using preprocessor defines. You can add those defines as compiler flags if you want to work around the problem, but I wouldn't really worry about it. You are already doing Objective-C programming after all, have you ever looked at the gargantuan amount of includes that get pulled in when you import something as innocuous as Foundation.h? Importing the full ObjectiveChipmunk.h header is like 1% in comparison.
I have an objc program and i would like to use a widget that is written in objc++ (namely https://launchpad.net/scintilla-cocoa). How do i go about this? Basically i want a new window controller object to interface with this objc++ library to define a scintilla text editor widget. Simply creating a new 'objc class' and accessing the library from there generates a bunch of errors related to the C++ class keyword and so on.
Thanks in advance
Since I'm the one who put you into the (hopefully rewarding :-)) trouble of using Scintilla, here I am.
Let's say we create a ScintillaView subclass, named ppScintillaEditor.
The file should have an .mm extension (e.g. ppScintillaEditor.mm)
The code would be roughly like this...
Interface
#import "Scintilla/ScintillaView.h"
#interface ppScintillaEditor : ScintillaView
{
// your iVars
}
// your properties / methods / whatever
Now, as for the implementation part, remember to put some initialization method to set up the view properly (as in the example accompanying Scintilla-cocoa; I mean the Test project)
Sidenote : Of course, you can create subclasses, categories or whatever on top the ScintillaView class, pretty much based on what you need - I, for example, have create a separate Category just in order to group there some ScintillaView specific commands (sooner or later, you'll notice that for some more advanced Scintilla manipulations, although it's there, it may need some polishing to be a bit more cocoa-friendly, so here you go...)
Now, last but not least...
To resolve the "bunch of errors related to the C++ class keyword and so on", as I've shown in my other video-response to your comment, all you have to do is :
Go to your project's Build Settings
Under Apple LLVM Compiler 3.0 - Preprocessing
Option Preprocessor Macros
Add to both Debug and Release :
SCI_NAMESPACE SCI_LEXER
And that's it. :-)
Hint : The above are defined by Scintilla to avoid clashes between C and non-C elements, like above... so, all it takes is to notify the preprocessor and the rest is taken care of....
you would create an objc class which has the interface your app needs, then implement and add the ivars and implement -- all behind a compilation firewall so the objc++ sources are not included in the header. your implementation would provide any necessary conversions.
it is like you have already done, but you remove the scintilla headers from the header for your wrapper -- they are visible only to your wrapper's implementation.
Update
To illustrate one possible approach:
MONScintillaWrapper.h
// no c++/scintilla sources should be included in this header
#import <Foundation/Foundation.h>
#interface MONScintillaWrapper : NSObject
- (void)setBackgroundColor:(NSColor *)pColor;
#end
MONScintillaWrapper.mm
#import "MONScintillaWrapper.h"
#implementation MONScintillaWrapper
{
scintilla::t_thing scintillaThing;
}
- (void)setBackgroundColor:(NSColor *)pColor
{
...convert pColor to a scintilla color and pass that to scintillaThing...
}
#end