I am wondering if libraries can be stateful. In other words, can libraries store variables within themselves with persistent values?
I think the answer is "no" but I'm just trying to confirm.
Most libraries I have used are written in C and are not object-oriented. They only consist of static functions which do work on a pointer you pass to them, but the actual block of memory pointed to by the pointer is physically located within the program's addressable space; not the library's.
Related
I meet a question about the interview test:
When a dll is loaded into memory, which part(s) can be shared between processes?
A. code segment
B. static variable global variable
C. external difinitions and references for linking
D. BSS segment
who can give me an answer and a clear explation?
Processes are actually isolated programs running multiple threads in an OS. Generally operating system policy says, All processes are memory isolated from each other.
Code Segment : [NOT SHARED]
BSS and Static Fields : [NOT SHARED]
Reason is very simple, why a operating system allow process A to access process B's binary? that's security and memory protection violation. process A could corrupt (if write access is given) process B memory.
what about External Definitions?
Here comes the interesting part, External definitions could be statically or dynamically linked.
statically linked library implies definitions are linked at compiled time and programs binary contains It's machine code.
dynamically linked implies definitions are linked just after user commands to load any program in memory. OS calls dynamic library loader to resolve external dependencies of the program by providing shared object's path.
This shared object is cached by operating system in a different page frame, and every time when a program demands for this library, It simply copy It's page frame to process's virtual memory; and do required dynamic linking. This way multiple process have same binary of a single library.
It save RAM memory and time in loading library from disk, Also dynamic linking reduces binary size of the program.
It is also possible that the OS choose to load library again from disk, and thus make two copies of same library. This is a part of dynamic linking operation. I don't go into more depth, but if you are really interested https://en.wikipedia.org/wiki/Dynamic_linker or just ping me in comments section.
But regarding BSS and static fields, It is again not shared; Whenever a write operation is performed on such region (which is shared). Operating System create a new copy of that region for the other process. This makes sure that both process have their own copy of BSS and static fields.
What makes programmatic introspection/reflection easier in virtual machines rather than native code?
I read somewhere that VMs by nature allow for better introspection/reflection capabilities but I cannot find more information about it online. Would like to know why.
I believe you mean higher-level languages vs lower-level languages instead of virtual machines.
Higher level languages like Java and C# have implemented reflection and introspection, so there are functions available to the developer to use this information.
Languages like C do not have any pre-built reflection capabilities.
Reflection is very expensive (time-consuming) for any language to run, and should not be used in code that needs to be extremely fast.
Programmatic introspection essentially means to examine & inspect the current call stack, or the current continuation. (Read Appel's book: Compiling with Continuations).
Few programming languages provide this ability. Scheme's call/cc reifies the current continuation, but give no standard ways to inspect it.
The current call stack might be inspectable (e.g. see GCC __builtin_return_address as an ad hoc example).
Most compilers (but not all) do not have an easy way to give information about the layout of the current call frame (however, the debugger DWARF format contains it).
And optimizing compilers (e.g. for C) usually don't give access to the offset of some local variable in the call frame (even if the compiler computes this offset). BTW, the same stack slot might be reused for different variables; read about register spilling.
See also J.Pitrat's CAIA system - the generated C code is able to organize the stack to be able to inspect it;
In a bytecode VM like JVM or NekoVM or Parrot, introspection is easier because each local variable has a well defined slot in the call frame. This is not the case for most compiled languages (e.g. C or C++) because the compiler is able to reuse (for optimization purposes) some slots, or even put a variable only in some machine register, without even allocating any call stack slot to spill it.
I am looking at this page about C++ differences from Objective C and it states this:
The dynamic nature of Objective C allows existing classes to be extended at runtime. Objective C allows you to define categories, related sets of extensions to objects you've already created. For example, in converting a text-based app into a graphics app, the code your objects needed to draw themselves could be compiled as a category and loaded at run-time only when needed. This saves memory and allows you to leave your original objects unmodified.
Now I am familiar with Categories and have used them, but I do not see how they lead to dynamic loading. If you import a Category file, is it not compiled along with the class it extends, taking up memory whenever you use that class, whether you use the Category methods or not?
You can load a bundle/plugin/framework at runtime. This is the dynamic nature of Objective-c that the quote references. It is not specific to Categories.
However, if the (compiled) code you load includes a Category on an existing Class, the extensions will work just as if they had been there all along. Ie a Class is not 'Frozen' at compile time, and loading a bundle/plugin/framework is one way to add new methods to an existing class at runtime.
This makes it relatively easy to implement a plugin architecture, or load code only when needed to make app startup time faster/keep memory footprint down, compared to some other C based compiled languages.
If you link with a static library containing a category, the linker will copy all of the category code into your executable file. If you link with a shared library, the shared library's entire code segment gets mapped into your process's address space, but it's paged in lazily, so you might not actually read all of the category code off of the disk unless you use it all.
But I think that's not really what the page is talking about.
Link-time libraries
First, let's talk about libraries that you tell the linker to link your app with.
Consider NSString. The NSString class is defined in the Foundation framework, which is a framework full of general-purpose classes useful in programs that have GUIs and in programs that don't have GUIs. So the NSString class as defined in Foundation doesn't include any code for drawing a string into a graphics context, because that code would (usually) be useless in a non-GUI app.
The AppKit framework (on OS X) manages a GUI. It's useful in a GUI to be able to draw strings to a graphics context, so AppKit contains a category on NSString that adds methods for drawing a string, like drawAtPoint:withAttributes:. UIKit (on iOS) does the same thing (but the methods are a little bit different).
So if you write a program on the OS X and use Foundation but don't use AppKit, your process won't load the AppKit NSString category and you won't pay the price for all of those graphics methods on NSString.
For a shared library like AppKit, the price is pretty trivial on modern hardware.
Now, you could do the same thing with your own libraries, which you might make static. Let's say you make a “TwitterModel” library for talking to Twitter. It's full of classes that model the things you find on Twitter, like accounts and tweets. But you don't include code for managing a GUI to display tweets.
Instead, you make another library, “TwitterGUI”, that (in addition to defining yet more classes) uses categories to add methods to the model classes in your “TwitterModel” library.
If you write a program that links to both TwitterGUI and TwitterModel, the executable file will contain all of the Objective-C code from both libraries. But if you write a command-line only program (no GUI) and only link it with TwitterModel, that program won't contain any of the GUI-related code. Oh, the savings!
Run-time libraries
Now let's consider shared libraries that you don't tell the linker to link your app with.
You can dynamically load new code into your process at runtime, using an API like dlopen or -[NSBundle load]. If the library contains categories, those categories will be added to the classes in your running program.
So, you could make your app optionally use a shared library if it exists on the user's system when he runs your app, by trying to load the library programmatically. If you succeed, you can call any category methods that you know the library defines. (And of course you can use the classes that the library provides, if any.) If you fail to load the library, you carefully avoid calling any of those category methods from the library.
Typically, though, we use a dynamic loading API to load a plugin, and the plugin provides some class that subclasses a base class, or conforms to a protocol, that we've defined specifically for plugins to implement. We just need to get the name of that class, and then we create an instance of it and send it the messages that we defined in our base class or protocol.
I could not find any good document on internet about STM32 programming. STM's own documents do not explain anything more than register functions. I will greatly appreciate if anyone can explain my following questions?
I noticed that in all example programs that STM provides, local variables for main() are always defined outside of the main() function (with occasional use of static keyword). Is there any reason for that? Should I follow a similar practice? Should I avoid using local variables inside the main?
I have a gloabal variable which is updated within the clock interrupt handle. I am using the same variable inside another function as a loop condition. Don't I need to access this variable using some form of atomic read operation? How can I know that a clock interrupt does not change its value in the middle of the function execution? Should I need to cancel clock interrupt everytime I need to use this variable inside a function? (However, this seems extremely ineffective to me as I use it as loop condition. I believe there should be better ways of doing it).
Keil automatically inserts a startup code which is written in assembly (i.e. startup_stm32f4xx.s). This startup code has the following import statements:
IMPORT SystemInit
IMPORT __main
.In "C", it makes sense. However, in C++ both main and system_init have different names (e.g. _int_main__void). How can this startup code can still work in C++ even without using "extern "C" " (I tried and it worked). How can the c++ linker (armcc --cpp) can associate these statements with the correct functions?
you can use local or global variables, using local in embedded systems has a risk of your stack colliding with your data. with globals you dont have that problem. but this is true no matter where you are, embedded microcontroller, desktop, etc.
I would make a copy of the global in the foreground task that uses it.
unsigned int myglobal;
void fun ( void )
{
unsigned int myg;
myg=myglobal;
and then only use myg for the rest of the function. Basically you are taking a snapshot and using the snapshot. You would want to do the same thing if you are reading a register, if you want to do multiple things based on a sample of something take one sample of it and make decisions on that one sample, otherwise the item can change between samples. If you are using one global to communicate back and forth to the interrupt handler, well I would use two variables one foreground to interrupt, the other interrupt to foreground. yes, there are times where you need to carefully manage a shared resource like that, normally it has to do with times where you need to do more than one thing, for example if you had several items that all need to change as a group before the handler can see them change then you need to disable the interrupt handler until all the items have changed. here again there is nothing special about embedded microcontrollers this is all basic stuff you would see on a desktop system with a full blown operating system.
Keil knows what they are doing if they support C++ then from a system level they have this worked out. I dont use Keil I use gcc and llvm for microcontrollers like this one.
Edit:
Here is an example of what I am talking about
https://github.com/dwelch67/stm32vld/tree/master/stm32f4d/blinker05
stm32 using timer based interrupts, the interrupt handler modifies a variable shared with the foreground task. The foreground task takes a single snapshot of the shared variable (per loop) and if need be uses the snapshot more than once in the loop rather than the shared variable which can change. This is C not C++ I understand that, and I am using gcc and llvm not Keil. (note llvm has known problems optimizing tight while loops, very old bug, dont know why they have no interest in fixing it, llvm works for this example).
Question 1: Local variables
The sample code provided by ST is not particularly efficient or elegant. It gets the job done, but sometimes there are no good reasons for the things they do.
In general, you use always want your variables to have the smallest scope possible. If you only use a variable in one function, define it inside that function. Add the "static" keyword to local variables if and only if you need them to retain their value after the function is done.
In some embedded environments, like the PIC18 architecture with the C18 compiler, local variables are much more expensive (more program space, slower execution time) than global. On the Cortex M3, that is not true, so you should feel free to use local variables. Check the assembly listing and see for yourself.
Question 2: Sharing variables between interrupts and the main loop
People have written entire chapters explaining the answers to this group of questions. Whenever you share a variable between the main loop and an interrupt, you should definitely use the volatile keywords on it. Variables of 32 or fewer bits can be accessed atomically (unless they are misaligned).
If you need to access a larger variable, or two variables at the same time from the main loop, then you will have to disable the clock interrupt while you are accessing the variables. If your interrupt does not require precise timing, this will not be a problem. When you re-enable the interrupt, it will automatically fire if it needs to.
Question 3: main function in C++
I'm not sure. You can use arm-none-eabi-nm (or whatever nm is called in your toolchain) on your object file to see what symbol name the C++ compiler assigns to main(). I would bet that C++ compilers refrain from mangling the main function for this exact reason, but I'm not sure.
STM's sample code is not an exemplar of good coding practice, it is merely intended to exemplify use of their standard peripheral library (assuming those are the examples you are talking about). In some cases it may be that variables are declared external to main() because they are accessed from an interrupt context (shared memory). There is also perhaps a possibility that it was done that way merely to allow the variables to be watched in the debugger from any context; but that is not a reason to copy the technique. My opinion of STM's example code is that it is generally pretty poor even as example code, let alone from a software engineering point of view.
In this case your clock interrupt variable is atomic so long as it is 32bit or less so long as you are not using read-modify-write semantics with multiple writers. You can safely have one writer, and multiple readers regardless. This is true for this particular platform, but not necessarily universally; the answer may be different for 8 or 16 bit systems, or for multi-core systems for example. The variable should be declared volatile in any case.
I am using C++ on STM32 with Keil, and there is no problem. I am not sure why you think that the C++ entry points are different, they are not here (Keil ARM-MDK v4.22a). The start-up code calls SystemInit() which initialises the PLL and memory timing for example, then calls __main() which performs global static initialisation then calls C++ constructors for global static objects before calling main(). If in doubt, step through the code in the debugger. It is important to note that __main() is not the main() function you write for your application, it is a wrapper with different behaviour for C and C++, but which ultimately calls your main() function.
Is it valid to develop a DLL in C++ that returns boost shared pointers and uses them as parameters?
So, is it ok to export functions like this?
1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);
In special: Does the reference count work across DLL boundaries or would the requirement be that exe and dll use the same runtime?
The intention is to overcome the problems with object ownership. So the object gets deleted when both dll and exe don't reference it any more.
According to Scott Meyers in Effective C++ (3rd Edition), shared_ptrs are safe across dll boundaries. The shared_ptr object keeps a pointer to the destructor from the dll that created it.
In his book in Item 18 he states, "An especially nice feature of
tr1::shared_ptr is that it automatically uses its per-pointer deleter
to eliminate another potential client error, the "cross-DLL problem."
This problem crops up when an object is created using new in one
dynamically linked library (DLL) but is deleted in a different DLL. On
many platforms, such cross-DLL new/delete pairs lead to runtime
errors. tr1::shared_ptr avoid the problem, because its default deleter
uses delete from the same DLL where the tr1::shared_ptr is created."
Tim Lesher has an interesting gotcha to watch for, though, that he mentions here. You need to make sure that the DLL that created the shared_ptr isn't unloaded before the shared_ptr finally goes out of scope. I would say that in most cases this isn't something you have to watch for, but if you're creating dlls that will be loosely coupled then I would recommend against using a shared_ptr.
Another potential downside is making sure both sides are created with compatible versions of the boost library. Boost's shared_ptr has been stable for a long while. At least since 1.34 it's been tr1 compatible.
In my opinion, if it's not in the standard and it's not an object/mechanism provided by your library, then it shouldn't be part of the interface to the library. You can create your own object to do the reference counting, and perhaps use boost underneath, but it shouldn't be explicitly exposed in the interface.
DLLs do not normally own resources - the resources are owned by the processes that use the DLL. You are probably better off returning a plain pointer, which you then store in a shared pointer on the calling side. But without more info it's hard to be 100% certain about this.
Something to lookout for if you expose raw pointers from a dll interface. It forces you to use the shared dll CRT, memory allocated in one CRT cannot be deallocated in a different CRT. If you use the shared dll CRT in all your modules ( dll's & exe's ) then you are fine, they all share the same heap, if you dont you will be crossing CRT's and the world will meltdown.
Aside from that issue, I agree with the accepted answer. The creation factory probably shouldn't define ownership & lifecycle management for the client code.
No it is not.
The layout of boost::shared_ptr<T> might not be the same on both sides of the DLL boundary. (Layout is influenced by compiler version, packing pragmas, and other compiler options, as well as the actual version of the Boost source code.)
Only "standard layout" (a new concept in C++11, related to the old "POD = plain old data" concept) types can safely be passed between separately-built modules.