I wonder the difference of import and include in Object-c
By the way, I am not clear about the difference of dynamic and static linking.
If I use a library with static linking,
is that mean I copy the code i need from library for my program and link with them?
Then my program can work with the code from library.
If i use a library with dynamic linking,
is that mean I only reference the code i need from library to my program when my program is running.
Then my program can work with the "reference code".
#import vs. #include and static vs. dynamic linking are two completely unrelated topics.
#include includes the contents of a file directly in another file, and is available in C (and therefore also in Objective-C). However, it's common to want to include the contents of a file only if that file hasn't already been included. (You don't, for example, want to declare the same variables twice; it'd cause compiler errors!) That's why #import was added in Objective-C; it does exactly that: includes the contents of a file only if that file hasn't already been #imported. If you're not sure what to use, you should probably be using #import.
Static vs. dynamic linking is completely different--linking happens after compilation, so it couldn't possibly be related to #import and #include, which are part of the source code. Your thoughts on linking are exactly correct, however--statically linked libraries are included in your app, and your users don't need them. Dynamically linked libraries are referenced, and must be present on your users' machines for your app to run.
Related
I've run into a somewhat unexpected behavior in Xcode/Objective-C. I know it's probably not advised, but if I want to make my own struct in_addr in a .m file, it seems I can't. This implies something rather strange about namespaces and symbol pollution in Objective-C. The same seems to apply for many other networking types and perhaps other POSIX-y things as well.
I came up with a very basic example that demonstrates this behavior. Note that this snippet is the entire contents of the .m file.
#define _SYS_SOCKET_H_
#define _NETINET_IN_H_
#include <stdint.h>
struct in_addr {
uint32_t foo;
};
which yields the build error Redefinition of 'in_addr'.
This implies some fairly strange things about Objective-C. For starters, I wouldn't expect <stdint.h> to bring in any networking types. But even allowing that it might, defining _NETINET_IN_H_ first should prevent the definition of struct in_addr. And yet even still, this code refuses to build.
Is it possible to somehow forgo this forced symbol visibility? Is there a list of symbols that are included, no matter what? Is there a good reason for this behavior?
edit: Stranger still, if i remove <stdint.h> and change the uint32_t to int, this actually does compile.
If you go into the Report navigator and read the full error emitted by the clang tool, you'll see a big hint:
In module 'Darwin' imported from /Users/csrstka/Desktop/asdfasdf/asdfasdf/main.m:1:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/netinet/in.h:302:12: note: field has name 's_addr' here
in_addr_t s_addr;
As you can see, the existing in_addr is coming from the Darwin module, which is implicitly imported due to your #include of stdint.h, which is part of the Darwin module. You can see this if you go to Product > Perform Action > Preprocess in Xcode—instead of copying in all the headers you've imported, there's just one line about importing Darwin.C.stdint.
Basically, there are a few purposes for modules; they improve compile times by cutting down on redundant compilation tasks, and they prevent people from messing with library headers via #defines like you're trying to do. ;-) For more on Objective-C modules, how they work, and the rationale behind them, see this link:
https://clang.llvm.org/docs/Modules.html#introduction
Of particular interest to your question are the following excerpts:
The primary user-level feature of modules is the import operation, which provides access to the API of software libraries. However, today’s programs make extensive use of #include, and it is unrealistic to assume that all of this code will change overnight. Instead, modules automatically translate #include directives into the corresponding module import. For example, the include directive
#include <stdio.h>
will be automatically mapped to an import of the module std.io. Even with specific import syntax in the language, this particular feature is important for both adoption and backward compatibility: automatic translation of #include to import allows an application to get the benefits of modules (for all modules-enabled libraries) without any changes to the application itself. Thus, users can easily use modules with one compiler while falling back to the preprocessor-inclusion mechanism with other compilers.
And later on:
If any submodule of a module is imported into any part of a program, the entire top-level module is considered to be part of the program. As a consequence of this, Clang may diagnose conflicts between an entity declared in an unimported submodule and an entity declared in the current translation unit, and Clang may inline or devirtualize based on knowledge from unimported submodules.
Or, if you'd prefer to turn them off and get more traditional C-like behavior, you can simply set Enable Modules (C and Objective-C) to No in Xcode's Build Settings, or compile without the -fmodules flag if you're using the command line.
I was searching on the internet about the differences between namespace , header file and library but I am still confused that what is the basic difference between them , please give an answer in the context of programming language not any specific language like C or C++
Namespace
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
Library
In programming, a library is a collection of precompiled routines that a program can use. The routines, sometimes called modules, are stored in object format. Libraries are particularly useful for storing frequently used routines because you do not need to explicitly link them to every program that uses them.
Header Files
Header files contain definitions of Functions and Variables, which is imported or used into any C++ program by using the pre-processor #include statement. Header file have an extension ".h" which contains C++ function declaration and macro definition.
thanks
libraries contain predefined function definitions.
header files contain predefined function declaration means prototypes and also contains macros as well
When ever we install some compiler,we select the suitable version of compiler that our OS supports that means every compiler has some set of library functions where OS uses them for I/O.
I know that .m files are where the implementation is and .h files have the method signatures, etc. When one wants to use a certain class in his class, then he imports the .h file. Preprocessor replaces the import .h file with the content of the .h file. What I don't understand is how come access to implementation become available from just preprocessor bringing the .h content? What is the runtime mechanism that allows this?
Importing the .h file isn't actually what does that, so you're correct to be confused!
When a program is compiled, each file is compiled to an "object file", and those are all linked together into an executable program. It's this linking step that provides access to the implementation.
Similarly, any libraries you use need to be linked against (Xcode's project templates do this for you for Foundation, UIKit/AppKit, and other common libraries). This type of linkage is done partially at compile time, then finished dynamically when your app launches, so that it gets the version of the libraries included with the OS instead of the version you compiled with.
Importing the header simply lets the compiler know what things are in the linked library so that it can compile code that references them. If you look up the functionality you use dynamically instead of letting the compiler do it (via dlopen, dlsym, NSClassFromString, NSSelectorFromString, etc...), then you can use linked code without importing its header.
I'm confused as to why __declspec(dllexport) or equivalent needs to go in the header file. Say I'm writing a library. Surely the users don't need to know or worry about whether symbols are exported or not, all they care about is that the function declarations are there and will presumably be linked against the shared or static library itself. So why can't all this boilerplate go into source files, for use only at build time?
The only use case I think of is a situation where someone is writing a wrapper of my library and needs to export all of my functions as well, but in general that is not the case - is it really worth the hassle of having all the export stuff inside public headers? Is there something I'm missing, is this a technical limitation of linkers..?
I'm asking because I like my headers and build system to be clean, and as dllexport stuff is generally set/not set based on whether we are building the library as a shared or static library, I find it strange that it should end up inside public headers since it's (to my understanding) fundamentally a build time concept. So can someone please enlighten me on what I am missing?
I'm not really sure I can provide a great answer. My impression is that it serves several purposes:
It speeds the loading of DLLs, particularly when lots of DLLs are used (because there are fewer exported symbols to search through)
It reduces the possibility of symbols colliding at run-time (because there are fewer exported symbols)
It allows the linker to complain about undefined symbols (instead of just assuming it might find them at run time.
I'm sure there are other reasons. I generally wrap my APIs in something like this:
#if defined(MY_LIB_CREATION)
#define MY_LIB_API __declspec(dllexport)
#else
#define MY_LIB_API __declspec(dllimport)
#endif
And then all of my API functions & classes are defined as MY_LIB_API:
class MY_LIB_API Foo {};
MY_LIB_API void bar();
And then in the project file defined MY_LIB_CREATION for the project implementing your library.
I have multiple app projects which all link to the same static library project. Each app project needs to compile the static library project using different settings.
At the moment I have a conditional compilation header in the static library project, let's call it ViewType.h which adds more types, typedefs, macros, etc specific to each view.
#define VIEW_A 1
#define VIEW_B 2
#define VIEW_C 3
#ifndef VIEWTYPE
#define VIEWTYPE VIEW_A
#endif
#if VIEWTYPE == VIEW_A
// further typedefs and defines tailored to VIEW_A
#elif VIEWTYPE == VIEW_B
// further typedefs and defines tailored to VIEW_B
#elif VIEWTYPE == VIEW_C
// further typedefs and defines tailored to VIEW_C
#endif
The problem here is that each app project needs to change the VIEWTYPE in the static library project, and every time I switch app projects I have to change the VIEWTYPE again.
Unfortunately it seems I can not define VIEWTYPE=2 (for example) as preprocessor macro in the app target. And I can't define this in the static library project either because all 3 projects include the same static library project, because the .xcodeproj is shared between the 3 apps (ie the .xcodeproj is dragged & dropped onto the app project; I'm not using a workspace).
I understand one issue is that the static library being a dependent target it is built first before the app target is even considered. So perhaps there's some way to make that decision which app the library is built for based on other conditionals (ie checking for a file, or including an optional app-specific header).
Question: How I can create a macro or otherwise perform conditional compilation based on macros/settings defined by the app target which are then adhered to by the static library project?
The first, simplest approach, is to get rid of the static library, and just include the source files directly into the dependent projects. I often find that intermediate static libraries are much more trouble than they're worth. Their one big benefit comes when they provide a significant build-performance improvement, but they can't here since you're rebuilding the static library for every final target anyway.
I will say that the use of a type #defines almost always makes me cry, and may suggest a design flaw that could be better handled. For instance, you may want to implement methods that return the class required (the way UIView layerClass does). Pre-processor trickery that changes type definitions can lead to extremely subtle bugs. (I just chased down a case of this last year… it was a horrible, horrible crash to figure out.)
That said, another approach for certain versions of this problem can be solved with xcconfig files. For example, if there are actually multiple copies of the static library (i.e. this is a library that is commonly copied into other projects), then you can use an xcconfig file that has an #include "../SpecialTypeDefs.xcconfig". That file would be provided by each project to set special declarations. Failure to define that file would lead to a complier error, so it's easy to not have an error.
But personally, I'd just include the files into the actual project directly and skip the library unless they're really enormous.