XYZ.dll defines a global variable int x.
ABC.c also defines the same global variable int x.
How can one link XYZ.dll to ABC.exe? How is this conflict in global namespace resolved?
This is a really good question, and I hope it gets a real answer. From what I can gather, a "global" symbol from a dll would have to be explictly imported via an associated header file. If you have two symbols that are the same, whichever symbol gets defined last, in the c file, is the one that would take precedence. That is, if you have ABC.c, and at the top, you would import XYZ.h, and then define int x. You either clobber the int x from XYZ.h, or you get a compile time error.
The variable int x has to be declared as extern int x in the header file of XYZ . And where ever you are going to use this variable just declare this variable. Like in ABC.c in the global space declare this variable like int x;
Related
I was trying to understand how programs use variables and I just got to ask some thing. I am using the following snippet to explain my question.
int x=10;
int *p;
p=&x; // now p stores the address of the variable x
Here P points to (holds the address of) X. And P itself has an address. I thought that there should be another pointer which points to this pointer. If so where is that pointer residing? Is this a file system concept? Similarly in the below case:
int x=10;
Where does our program find the address of the variable X so that it can access the value stored at the address referenced by x. Is X it self acting as a pointer? If so, again there should be a way to access the address of X which holds an address that holds an integer value 10.
If I am right: for every variable declared, there is a pointer (or may be an index table) that points to the address of the variable so that we can use the value at an address referenced by the declared variable. So my question will be where is that?
If I am wrong : my question will be help me to understand it better?
When you build a program, the compiler (and in some cases the linker) replaces every variable name with either a memory address or a register.
So the executable image of your program (for example, exe file on Windows), does not contain any of those variables, just plain memory addresses and registers.
I am curious to know if there is any way to find a global variable at runtime, much like NSClassFromString. The variable, a BOOL, is defined in a static library and I found the name by using "nm" which gave this output: "0001924d b _gStartSessionCalled". When debugging in XCode I can add an expression "gStartSessionCalled" and see the value change as the app is running.
What I want to do is find the value of gStartSessionCalled and also change the value. I know it's kind of weird to do this but please disregard the reason why.
The lowercase letter "b" in the nm output
0001924d b _gStartSessionCalled
indicates that gStartSessionCalled is a local (non-external) symbol. It could for example be defined as
static BOOL gStartSessionCalled;
in your library. As far as I know, you cannot access local symbols from outside the object file in which it they are defined.
The debugger can use the symbol table to find the address and display the variable, but the linker refuses to link against a local symbol from a different object file.
A global variable is not an Objective-C specific construct. It is plain C and you can access every global variable when knowing its name by declaring it like
extern <type> <name>;
e.g. in your case
extern BOOL gStartSessionCalled;
…
gStartSessionCalled = YES;
Update:
If you do not know the name of the variable at compile time, you still may find the symbols address at runtime using something like dlsym. I don't know if it is the same on MacOS as on Linux, but there will be something similar.
In my game I have a header file that contains properties and functions for seasons in my game. These properties are all static and include a float representing the current season and another float representing the current point in the transition between seasons, being zero if it isn't transitioning.
Several functions throughout my game rely on the transition (two at this point) and one is working perfectly. Although, in another instance this isn't working at all.
In the class responsible for controlling the background for my game, when ever the "SeasonTransition" variable is referenced it just comes up zero. But in the other class, where the variable is referenced exactly the same way, it comes up with the real value.
This is a picture after a breakpoint has been called after the game could update a few frames:
Once again these variables are declared in a c header file:
#import "somestuff.h"
static float SeasonTransition
etc...
This shouldn't be doing this right? How could I fix this?
EDIT:
The Season.h file is as follows:
//GL.h contains different functions and global variables to be used anywhere in the project.
//This file, like Season.h is a singular header file with static declarations, and is setup
//the same way. I have been developing this from the start of the project and havent had any
//problems with it.
#import "GL.h"
static float currentSeason;
static float SeasonTransition;
static void UpdateSeason(){
currentSeason += 0.0002f;
float TransitionLength = 0.15f;
float SeasonDepth = Clamp(currentSeason - floorf(currentSeason), 0, TransitionLength);
float bigTL = TransitionLength / 4;
float endTL = TransitionLength;
float Speed2 = 0;
float Speed1 = 1;
float bRatio = SeasonDepth / bigTL;
float eRatio = SeasonDepth / endTL;
SeasonTransition = (SeasonDepth < TransitionLength) ?
((SeasonDepth < bigTL) ?
(Speed1 * bRatio) + (Speed2 * (1.0f - bRatio)) :
(Speed1 * (1.0f - eRatio)) + (Speed2 * eRatio))
:
Speed2;
}
If you put static float SeasonTransition; into two separate C files (or one header file included by two separate C files), each C file will have its own independent copy of the variable.
If one of those C files then modifies the variable, it will modify its copy. It will not touch the one in the other C file. That sounds like the situation you're in.
The normal way to do this is to define the variable in one and declare it external in the other, something like:
file1.c:
int myVar; // it exists here.
file2.c:
extern int myVar; // it exists, but elsewhere.
You don't want to mark it static in the first since that effectively makes it invisible to the second. And you mark it extern in the second so that it knows the variable exists elsewhere (in the first).
You would actually see the effect if it weren't static. When the linker came to link those two files together, it would complain about having two variables with the same name.
There are many variations on how to do that, I've shown the simplest. It's probably better to have something like:
file1.h:
extern int myVar; // so everyone knows about the variable
// just by including this.
file1.c:
#include "file1.h" // or import for ObjC.
int myVar; // the actual variable.
file2.c:
#include "file1.h" // now we know about it, in the OTHER C file.
I could be wrong but I think the problem might be you don't quit understand how include/import work. These are not quit language features but preprocessor feature. When you include somewhere in a file, your say take the entire contents of that other file and stick it in here before your start compiling. So if you include the same header file in multiple different other files you will end up with multiple version of that static variable, with out the static you will get a compiler error because you have redefined the same variable multiple times. import works almost the same except if the preprocessor determines that the included file has already be include into the destination file (could be indirectly through another include), then it will not include the file again. If you understand this you can then see that declaring static variable within you header is quit strange, because you will end up with multiple versions of that variable everywhere that header is included. Normally you want to make the variable global in which case you define it in a .c or .m file and then declare it extern in the header or you want the variable to be private then you declare it static in the .c or .m file.
What static does is to hide the variable declaration from the linker, so the linker can not recognise that all the different declarations of the same name should be treated as the same variable.
#ifndef Season_h
#define Season_h
... your header stuff
#endif
Also, if you dont call updateSeason seasonTransition will be zero.
I have a .h file that defines a few hundred constants. Let's assume this to be one of them:
#define KDSomeItem 1
I know that the Objective-C runtime API can be used to retrieve a list of instance variable names: like detailed in this question: How do I list all fields of an object in Objective-C?
I also know that the getter [object valueForKey:theName] can be used to access the ivars as found in an earlier question of mine: How to access a property/variable using a String holding its name
My question is can something simmilar be done with constants? That is can I:
a) get a list of all constants programmatically
b) access a constant if I have a string holding its name
e.g. if I had a String like this NSString * theName = #"KDSomeItem"; could I evaluate my constant using this string?
You would not be able to do this: unlike instance variables, #define-d constants do not leave a trace after the preprocessor is done with them. They leave no metadata behind - all instances of KDSomeItem in the body of your program will be replaced with 1 even before the Objective C compiler proper gets to analyze your code.
If you need the constant names to be available at run time, you would need to build all the necessary metadata yourself. In order to do that, you may want to look into "stringizing" operator of the preprocessor:
#define STR(X) #X
This macro can be applied to a preprocessor constant, and produce a C string literal with its name:
const char *nameOfKDSomeItem = STR(KDSomeItem); // same as "KDSomeItem"
Nope. Your constant is a preprocessor macro. It is textually substituted into your source code where you use it.
In the header of the class, outside of interface declaration, I've declared global constants:
NSString * const gotFilePathNotification = #"gotFilePath";
NSString * const gotResultNotification = #"gotResultOfType";
gotResultNotification is used only in this class (yet), but I reference gotFilePathNotificaion in another class implementation. To do it, I import this header.
When I try to compile, I get a duplicate symbol linker error about gotFilePathNotification in this header. Why does it happen?
You have two identifier(s) with same name across two different compilation unit(s) at file scope. This violates One Definition Rule. Instead you need to -
Declare the global variables marking to have external linkage in a header file.
extern NSString * const gotFilePathNotification;
Now provide the definition in only one source file.
NSString * const gotFilePathNotification = #"gotFilePath";
Now where ever you need to use these variables, include the header in the source file.
You need to declare them extern in the header file and define them in implementation file. See this question for clarification. Global Variables in Cocoa/Objective-C? .
The second response provides the clarification that I will reiterate here. The default storage qualifier for variables is static. This means when you try to link two different files with the same variable, as will happen when you import your header file, the linker will construe that the variable is multiply-defined.
Also make sure you're including the h file and not the m file. This was driving me nuts.