Is this possible to update a Objective-C library in run time? - objective-c

Just leave alone the Apple policy, just talking about the Objective-C language only,
Assume that my programme calling a .a library. Is this possible to grep the .a from the
internet, and run a newer version of .a instead of old .a?
Thanks.

Not for statically linked libraries (.a), at least with any level of sanity. You can certainly do it with dynamically loaded libraries (.so); it's one of the normal use cases. Have a look at dlopen, dlclose and dlsym from the dynamic loader (https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/MachOReference/Reference/reference.html).

This is not just iOS, but OS X apps (and probably other Unixes in general)
Static libraries (.a files) cannot be replaced while the program is running because they are part of the application binary. The application binary is mapped into the process's address space. If you try to change any part of it, you'll almost certainly end up crashing the app.
Dynamic libraries (.so files) are replaceable in theory. However, most applications load them up once at the beginning or when first needed and then they become part of the application's address space. I've heard that it is theoretically possible for an application to unload a dynamic library, but I've never seen it done in any real Cooca application.

Related

How to load .dll file which returns assembly in Objective-C?

Is it possible to load .dll or static library(.a) file programmatially which returns assembly in objective-c for mac os x?
How assembly loading & unloading done in objective-c for mac osx?
I'll admit that even after reading Microsoft's documentation on the Assembly Class, it's still not clear to me what an Assembly is. They say:
Represents an assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application.
The "reusable, versionable and self-describing" part sounds like a framework.
If indeed that's what you want to load, then you have a number of options. Your best best is to just link against the framework. The OS will automatically load it for you when your app starts up.
If you want to load it manually, there are a number of ways to do that. If it's a framework you're going to ship with your application, then you can simply put it into your app bundle's Frameworks folder, and then use:
NSBundle* frameworkBundle = [NSBundle bundleWithIdentifier:#"<your bundle's identifier>"];
if (frameworkBundle != NULL)
{
[frameworkBundle load];
}
You can also use dlopen() (see man dlopen(3) for details). This will load a dynamic library into your process space.
I have never had a reason to use dlopen() directly. I usually just link against the framework. On those rare occasions where my app may need to run on an older OS that doesn't support the framework, I have used the manual loading described above via NSBundle.

How do I link multiple libraries in a Firebreath plugin?

Does anyone know where I can find a Firebreath sample (either Mac OS X or Windows) that illustrates how to create a plugin that includes 1 or more other libraries (.DLLs or .SOs) that each rely on other sub-projects built as static libraries (LIBs)?
For example, let's say that the Firebreath plugin is called PluginA, and that PluginA calls methods from DLL_B and DLL_C. DLL_B and DLL_C are C++ projects. DLL_B calls methods from another project called LIB_D, and DLL_C calls methods from a project called DLL_E.
Therefore, the final package should contain the following files:
PluginA.dll
DLL_B.dll (which also incorporates LIB_D)
DLL_C.dll
DLL_E.dll
I am currently forced to dump all source files in the pluginA solution, but this is just a bottleneck (for example I cannot call libraries written in other languages, such as Objective-C on Mac OS X).
I tried following the samples on Firebreath, but couldn't get them to work, and I found no samples from other users that claimed they were able to get it to work. I tried using CMAKE, and also running the solutions directly from X-Code, but the end result was the same (received linking errors, after deployment DLL_C couldn't find DLL_E etc.)
Any help would be appreciated - thank you,
Mihnea
You're way overthinking this.
On windows:
DLLs don't depend on a static library because if they did it would have been compiled in when they were built.
DLLs that depend on another DLL generally just need that other DLL to be present in the same location or otherwise in the DLL search path.
Those two things taken into consideration, all you need to do is locate the .lib file that either is the static library or goes with the .dll and add a target_link_library call for each one. There is a page on firebreath.org that explains how to do this.
On linux it's about the same but using the normal rules for finding .so files.

How to strip Objective-C symbols from OS X binary?

OK, I know there have been other posts about how you can't actually strip Objective-C symbols from an OS X binary because they're necessary for Obj-C to work at all, but my case is a bit different.
I have a single binary which is a bundle. It is intended to be used as either a VST plugin, or an AudioUnit plugin. The idea is that the binary contains all the entry points for both formats, and you just compile it once, and then name one copy with ".vst" for the VST version, and ".component" for the AU version. (This is using the JUCE framework BTW.)
The problem is that for the AU side, you must export an Obj-C class for creating the Cocoa UI view. On the VST side, this class will never be used. But if you have a host like Ableton Live which allows you to simultaneously load both AU and VST versions of the same plugin, now we run into the typical Obj-C namespace collision issue.
On the VST side, that particular Obj-C class will never get used. So what I'd like to do is to strip those Obj-C classes from the resulting binary using "strip". This still maintains the advantage of just compiling everything once for both formats.
Anyway, I've tried using "strip -R stripfile.txt <path to binary>", where stripfile.txt contains the symbols I want to strip, but it always fails saying that the symbols can't be found in the binary. I've tried mangling the names in the strip file, but that doesn't help (or I'm doing it wrong).
Here are the relevant symbols that I want to strip, as output by "nm -m":
000000000003bb00 (__TEXT,__text) non-external -[JuceDemoProjectAU description]
000000000003bb60 (__TEXT,__text) non-external -[JuceDemoProjectAU interfaceVersion]
000000000003ba00 (__TEXT,__text) non-external -[JuceDemoProjectAU uiViewForAudioUnit:withSize:]
0000000000b02398 (__DATA,__objc_data) external _OBJC_CLASS_$_JuceDemoProjectAU
0000000000b023c0 (__DATA,__objc_data) external _OBJC_METACLASS_$_JuceDemoProjectAU
Any ideas?
BTW, I have subsequently been able to dynamically register the class in question (using a unique name), which also solves the problem. However, if I could get strip working, I could potentially deploy a solution for already existing binaries in the field.
You can not just simply strip a class from a binary. What you can do however is to trick the Objective-C runtime into believing your plugin does not contain any Objective-C code. Just change __objc_imageinfo into __objc_imageinfX for example in your VST plugin binary. You can do it easily with perl:
perl -pi -e 's/__objc_imageinfo/__objc_imageinfX/g' <path to binary>
After patching the VST plugin, all the Objective-C initialization will be bypassed and you won’t see this error message: Class JuceDemoProjectAU is implemented in both …/VSTPlugin and …/AUPlugin. One of the two will be used. Which one is undefined.
Beware, you should really not use this trick! The appropriate solution to your problem is either to compile two different version of your plugin or to register classes dynamically as others suggested.
There was a thread about something similar to this on the coreaudio-list last year: Collision between Cocoa classes for AU and VST plugins.
The solution offered was to register the classes dynamically which is what you say you already have working. If there was a way to strip the symbols like you wanted, I'm sure these guys would have known about it.

Static Library using frameworks in specific projects

I have created a static library containing all my generic classes. Some of these classes use frameworks.
Now I have two projects, one that uses some classes that use frameworks, and one that doesn't use any of the classes that use frameworks.
Because Static Libraries don't support including frameworks (if I am correct). I have to include the frameworks in the project that uses them. But when I compile the project that doesn't use any of the framework-classes the compiler breaks because it still requires the frameworks. Now I know it tries to compile all the (unused) classes from the library because I use the Linker Flag '-ObjC' to prevent 'unrecognized selector' errors.
Does anyone know how to compile only the required source files per project? And prevent from all frameworks having to be included in all projects that use my static library?
First of all, you are right in that a static library cannot include any framework nor other static libraries, it is just the collection of all object files (*.obj) that make up that specific static library.
Does anyone know how to compile only the required source files per project?
The linker will by default only link in object files from the static library that contain symbols referenced by the application. So, if you have two files a.m and b.m in your static library and you only use symbols from a.m in your main program, then b.o (the object file generated from b.c) will not appear in your final executable. As a sub-case, if b.m uses a function/class c which is only declared (not implemented), then you will not get any linker errors. As soon as you include some symbols from b.m in your program, b.o will also be linked and you will get linker errors due to the missing implementation of c.
If you want this kind of selection to happen at symbol rather than at object level granularity, enable dead code stripping in Xcode. This corresponds to the gcc option -Wl,-dead_strip (= linker option -dead_strip in the Build settings Info pane for your project). This would ensure further optimization.
In your case, though, as you correctly say, it is the use of the "-ObjC" linker flag that defeats this mechanism. So this actually depends on you. If you remove the -Objc flag, you get the behavior you like for free, while losing the stricter check on selectors.
And prevent from all frameworks having to be included in all projects that use my static library?
Xcode/GCC support an linking option which is called "weak linking", which allows to lazily load a framework or static library, i.e., only when one of its symbols is actually used.
"weak linking" can be enabled either through a linker flag (see Apple doc above), or through Xcode UI (Target -> Info -> General -> Linked Libraries).
Anyhow, the framework or library must be available in all cases at compile/link time: the "weak" option only affects the moment when the framework is first loaded at runtime. Thus, I don't think this is useful for you, since you would need anyway to include the framework in all of your projects, which is what you do not want.
As a side note, weak_linking is an option that mostly make sense when using features only available on newer SDK version (say, 4.3.2) while also supporting deployment on older SDK versions (say, 3.1.3). In this case, you rely on the fact that the newer SDK frameworks will be actually available on the newer deployment devices, and you conditionally compile in the features requiring it, so that on older devices they will not be required (and will not produce thus the attempt at loading the newer version of the framework and the crash).
To make things worse, GCC does not support a feature known as "auto-linking" with Microsoft compilers, which allow to specify which library to link by means of a #pragma comment in your source file. This could offer a workaround, but is not there.
So, I am really sorry to have to say that you should use a different approach that could equally satisfy your needs:
remove the -ObjC flag;
split your static library in two or more parts according to their dependencies from external frameworks;
resort to including the source files directly.
Abour second part of your question, you can mark a linked framework as Optional :
About first part, it is not clear to me what you intend to do:
A library being declared in a project
A project declaring which files are compiled (via Target > Build phases > Compile sources)
Unless setting complex build rules to include or not files, which if I remember well can be done using .xcconfig files, I don't see any other solutions than splitting your Library. Which I would recommend, for its ease. You should even do several targets in the same project... You could also just use precompiler MACROS (#ifdef...) but that depends on what you want to do.
It sounds like you have library bloat. To keep things small I think you need to refactor your library into separate libraries with minimal dependencies. You could try turning on "Dead Code Stripping" in the "Linker Flags" section of the build target info (Xcode 3.x) to see if that does what you want (doesn't require frameworks used by classes that are dead-stripped.)
When you link against a framework on iOS I don't think that really adds any bloat since the framework is on the device and not in your application. But your library is still a bit bloated by having entire classes that never get used but are not stripped out of the library.
A static library is built before your app is compiled, and then the whole thing is linked into your app. There's no way to include some parts of the library but not others -- you get the whole enchilada.
Since you have the source code for the library, why not just add the code directly to each application? That way you can control exactly what goes into each app. You can still keep your generic classes together in the same location, and use the same code in both apps, but you avoid the hassle of using a library.

DLL and LIB files - what and why?

I know very little about DLL's and LIB's other than that they contain vital code required for a program to run properly - libraries. But why do compilers generate them at all? Wouldn't it be easier to just include all the code in a single executable? And what's the difference between DLL's and LIB's?
There are static libraries (LIB) and dynamic libraries (DLL) - but note that .LIB files can be either static libraries (containing object files) or import libraries (containing symbols to allow the linker to link to a DLL).
Libraries are used because you may have code that you want to use in many programs. For example if you write a function that counts the number of characters in a string, that function will be useful in lots of programs. Once you get that function working correctly you don't want to have to recompile the code every time you use it, so you put the executable code for that function in a library, and the linker can extract and insert the compiled code into your program. Static libraries are sometimes called 'archives' for this reason.
Dynamic libraries take this one step further. It seems wasteful to have multiple copies of the library functions taking up space in each of the programs. Why can't they all share one copy of the function? This is what dynamic libraries are for. Rather than building the library code into your program when it is compiled, it can be run by mapping it into your program as it is loaded into memory. Multiple programs running at the same time that use the same functions can all share one copy, saving memory. In fact, you can load dynamic libraries only as needed, depending on the path through your code. No point in having the printer routines taking up memory if you aren't doing any printing. On the other hand, this means you have to have a copy of the dynamic library installed on every machine your program runs on. This creates its own set of problems.
As an example, almost every program written in 'C' will need functions from a library called the 'C runtime library, though few programs will need all of the functions. The C runtime comes in both static and dynamic versions, so you can determine which version your program uses depending on particular needs.
Another aspect is security (obfuscation). Once a piece of code is extracted from the main application and put in a "separated" Dynamic-Link Library, it is easier to attack, analyse (reverse-engineer) the code, since it has been isolated. When the same piece of code is kept in a LIB Library, it is part of the compiled (linked) target application, and this thus harder to isolate (differentiate) that piece of code from the rest of the target binaries.
One important reason for creating a DLL/LIB rather than just compiling the code into an executable is reuse and relocation. The average Java or .NET application (for example) will most likely use several 3rd party (or framework) libraries. It is much easier and faster to just compile against a pre-built library, rather than having to compile all of the 3rd party code into your application. Compiling your code into libraries also encourages good design practices, e.g. designing your classes to be used in different types of applications.
A DLL is a library of functions that are shared among other executable programs. Just look in your windows/system32 directory and you will find dozens of them. When your program creates a DLL it also normally creates a lib file so that the application *.exe program can resolve symbols that are declared in the DLL.
A .lib is a library of functions that are statically linked to a program -- they are NOT shared by other programs. Each program that links with a *.lib file has all the code in that file. If you have two programs A.exe and B.exe that link with C.lib then each A and B will both contain the code in C.lib.
How you create DLLs and libs depend on the compiler you use. Each compiler does it differently.
One other difference lies in the performance.
As the DLL is loaded at runtime by the .exe(s), the .exe(s) and the DLL work with shared memory concept and hence the performance is low relatively to static linking.
On the other hand, a .lib is code that is linked statically at compile time into every process that requests. Hence the .exe(s) will have single memory, thus increasing the performance of the process.