android: Unable to access struct static data members - android

I'm having the next kind of error when linking the application:
undefined reference to 'MyStructure::K_VARIABLE_A
undefined reference to 'MyStructure::K_VARIABLE_B
...
The structure is defined inside "MyStructure.h" as:
struct MyStructure
{
const static int K_VARIABLE_A=1;
const static int K_VARIABLE_B=2;
...
}
How can i get rid of this error?
My source code compiles successfully for Windows platform but I get the error mentioned above when compiling for the android platform.
The header of this structure is properly included in the .cpp file.
Thanks in advance.

The preferred way to define constant values in the scope of a class/struct is this:
struct MyStructure
{
enum
{
K_VARIABLE_A=1,
K_VARIABLE_B=2, // Note that you CAN keep the trailing comma
...
};
};

The construct which you are using is called as In-Class Initialization. It is a valid syntax for integral constant types but it maynot work with some compilers.
Solution is to do:
const int MyStructure::K_VARIABLE_A=1;
const int MyStructure::K_VARIABLE_B=2;
in one of your cpp(Implementation) files.

For each of your static variables you will need to declare them in an compilation unit (traditionally .cpp file) so that they have storage space as such
#include "Mystructure.h"
const int MyStructure::K_VARIABLE_A = 1;
const int MyStructure::K_VARIABLE_B = 2;
// other stuff here...
This is because static members do not belong to any instance of the structure/class, but need storage space declared somewhere. The compilers leave it up to the programmer to specify which compilation unit contains the storage for the static members, but traditionally they will be placed in the .cpp file corresponding to the .h file.

Related

Where to put Scudo allocator __scudo_default_options callback?

From Scudo page:
Some parameters of the allocator can be defined on a per-process basis through several ways:
Statically: Define a __scudo_default_options function in the program that returns the options string to be parsed. This function must have the following prototype: extern "C" const char *__scudo_default_options().
Dynamically: Use the environment variable SCUDO_OPTIONS containing the options string to be parsed. Options defined this way override any definition made through __scudo_default_options.
Im fairly new to Android, could someone help me understand where to put functions like __scudo_default_options in cpp code, I have MainActivity.cpp and MidiManager.cpp
The function can be located anywhere within the application, as long as it's discoverable by the linker. Putting it in the vicinity of your main compilation unit is probably better.
You want to make sure that the symbol has a public visibility.
You can refer to the example in the tests here:
https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test_main.cpp#L23
eg. in MainActivity.cpp, something to the extent of:
extern "C" __attribute__((visibility("default"))) const char *
__scudo_default_options() {
return "quarantine_size_kb=256:thread_local_quarantine_size_kb=128:"
"quarantine_max_chunk_size=512";
}

I want to call c language through android, call assembly language through c language, but it appears undefined reference to `MyASMTest (int, int) ' [duplicate]

I am trying to call external C++ function from NASM. As I was searching on google I did not find any related solution.
C++
void kernel_main()
{
char* vidmem = (char*)0xb8000;
/* And so on... */
}
NASM
;Some calls before
section .text
;nothing special here
global start
extern kernel_main ;our problem
After running compiling these two files I am getting this error: kernel.asm(.text+0xe): undefined reference to kernel_main'
What is wrong here? Thanks.
There is no standardized method of calling C++ functions from assembly, as of now. This is due to a feature called name-mangling. The C++ compiler toolchain does not emit symbols with the names exactly written in the code. Therefore, you don't know what the name will be for the symbol representing the function coded with the name kernel_main or kernelMain, whatever.
Why is name-mangling required?
You can declare multiple entities (classes, functions, methods, namespaces, etc.) with the same name in C++, but under different parent namespaces. This causes symbol conflicts if two entities with the name local name (e.g. local name of class SomeContainer in namespace SymbolDomain is SomeContainer but global name is SymbolDomain::SomeContainer, atleast to talk in this answer, okay) have the same symbol name.
Conflicts also occur with method overloading, therefore, the types of each argument are also emitted (in some form) for methods of classes. To cope with this, the C++ toolchain will somehow mangle the actual names in the ELF binary object.
So, can't I use the C++ mangled name in assembly?
Yes, this is one solution. You can use readelf -s fileName with the object-file for kernel_main. You'll have to search for a symbol having some similarity with kernel_main. Once you think you got it, then confirm that with echo _ZnSymbolName | c++filt which should output kernel_main.
You use this name in assembly instead of kernel_main.
The problem with this solution is that, if for some reason, you change the arguments, return value, or anything else (we don't know what affects name-mangling), your assembly code may break. Therefore, you have to be careful about this. On the other hand, this is not a good practice, as your going into non-standard stuff.
Note that name-mangling is not standardized, and varies from toolchain to toolchain. By depending on it, your sticking to the same compiler too.
Can't I do something standardized?
Yep. You could use a C function in C++ by declaring the function extern "C" like this
extern "C" void kernelMain(void);
This is the best solution in your case, as your kernel_main is already a C-style function with no parent class and namespace. Note that, the C function is written in C++ and still uses C++ features (internally).
Other solutions include using a macro indirection, where a C function calls the C++ function, if you really need to. Something like this -
///
/// Simple class containing a method to illustrate the concept of
/// indirection.
///
class SomeContainer
{
public:
int execute(int y)
{
}
}
#define _SepArg_ , // Comma macro, to pass into args, comma not used directly
///
/// Indirection for methods having return values and arguments (other than
/// this). For methods returning void or having no arguments, make something
/// similar).
///
#define _Generate_Indirection_RetEArgs(ret, name, ThisType, thisArg, eargs) \
extern "C" ret name ( ThisType thisArg, eargs ) \
{ \
return thisArg -> name ( eargs ); \
} \
_Generate_Indirection_RetEArgs(int, execute, SomeContainer, x, int y);

What is the meaning of static const and const in dart programming language?

I watch online tutorial on YouTube in which the tutor says instance variable can be final but cannot be const therefor if you want a Constant at class level then make it static const . My question is what is the need to use static const while we have const keyword whose job is to define a variable that is constant throughout the variable.
Video link : https://www.youtube.com/watch?v=IYZqVOH6oSU at 2:24
According to this article :
"static", "final", and "const" mean entirely distinct things in Dart:
"static" means a member is available on the class itself instead of on
instances of the class. That's all it means, and it isn't used for
anything else. static modifies members.
"final" means single-assignment: a final variable or field must have
an initializer. Once assigned a value, a final variable's value cannot
be changed. final modifies variables.
"const" has a meaning that's a bit more complex and subtle in Dart.
const modifies values. You can use it when creating collections,
like const [1, 2, 3], and when constructing objects (instead of new)
like const Point(2, 3). Here, const means that the object's entire
deep state can be determined entirely at compile time and that the
object will be frozen and completely immutable.
My question is what is the need to use static const while we have const keyword whose job is to define a variable that is constant throughout the variable.
I think the main reason why you need to add the keyword static when declaring a const field in a class is readability so you are absolutely sure your understand that this variable will be same in every instance of the class.
Confusion can happen since final variables are allowed (and often are) to have different values in each instance of the class since final just means "Once assigned a value, a final variable's value cannot be changed.".
Since const mens compile time constant, it will always stay the same for all instances of a class which means it will always be static. But to make that fully clear for the developer, we need to write static even if the compiler could figure that out itself.
But again, that is only my guess. :)
Suppose const on a member did not require static, and you had:
class Foo {
const k = 42;
}
How do you access it?
Foo.k should be legal; since the value is always the same, you shouldn't need to construct a Foo object first.
What about Foo().k? Since there's no static keyword, it looks like it might be legal too. But if that's allowed, then there are bunch of cases you need to consider and define behaviors for:
Foo fooInstance = null;
print(fooInstance.k);
print(fooInstance?.k);
class Derived extends Foo {
const k = 9;
}
fooInstance = Derived();
print(fooInstance.k);
It seems simpler and clearer to me to require that const members also be static.

Referencing values in structures

I am looking at opcommon.cpp in Android 4.3 and comparing it to the same file in 4.1.1
In both 4.1.1 and 4.3 the file Object.h defines the structure Instfield as
struct InstField : Field {
int byteOffset;
};
and the structure Field as
struct Field {
ClassObject* clazz; /* class in which the field is declared */
const char* name;
const char* signature; /* e.g. "I", "[C", "Landroid/os/Debug;" */
u4 accessFlags;};
now my question is pretty simple:
given the declaration InstField* ifield;
opcommon has changed from using ifield->field.name in 4.1.1 to using ifield->name in 4.3
to retrieve the name variable.
What is the difference and is either better? If not why would they change it?
I could not google this question because the -> was just ignored an I don't know the word to describe the operator. eg field.name is referencing a variable in a structure and -> is used to dereference pointers and does the same but what's it's name?
Another tiny question on terminology, is the InstField structural definition a wrapper or an extension?
It would have been helpful if you had posted code snippets from 4.1.1 also. ifield->field.name suggests that field itself is a member of the struct InstField and that field is also a struct with a member name (could be any struct, not necessarily of type Field). ifield->name on the other hand suggests that name itself is a member of the struct InstField (by Inheritance) and is not a member of a member. You need to look at the part of 4.1.1 where InstField is defined. It's probably different than this definition which you got from 4.3.

What is the origin of "mThis"?

We have some devs on Android part of our application who actively use prefixing of class member variables with "m*".
What is the origin of "mThis" which is basically:
class SomeClass {
private final SomeClass mThis;
SomeClass() {
mthis = this;
}
}
and this notation in general?
Actually I guess the question is more about the m-prefix, not the goal of having this as your own field.
So regarding the prefix, this is a coding convention used by android team: all member variables (aka fields) are prefixed with "m". That's it, basically. Other android developers might use it because they have browsed through android sources and have deemed it appropriate to use this convention in their own code.
BTW, it's not common in general java programming, I believe common java coding standards usually discourage using any kind of prefixes for anything.
I assume it comes handy when you need to pass a reference to the instance in an inner class, and you don't want to use the "fully qualified" this. i.e SomeClass.this. Nevertheless, it seems redundant to me.
This article suggests it comes from ancient habits peculiar to the Microsoft ecosystem -- however, prefixing members of structs with some shorthand of the struct it is contained in is an old C habit from the days when identifiers, all identifiers (include structure member names), had to be unique in the first eight characters. Prefixing the names with a short-hand version of the name of the containing structure was an easy mechanism to ensure unique names:
struct inode {
int number;
struct device *dev;
}
struct file_descriptor {
int number;
struct inode *i;
}
In this case, number is duplicated, non-unique, and trouble.
Newer versions of C made this a non-issue by placing struct names into their namespaces, but some portion of this habit has carried over: the Linux kernel, for example, is filled with:
struct iattr {
unsigned int ia_valid;
umode_t ia_mode;
uid_t ia_uid;
....
and
struct inode {
/* RCU path lookup touches following: */
umode_t i_mode;
uid_t i_uid;
gid_t i_gid;
const struct inode_operations *i_op;
struct super_block *i_sb;
...
where the leading ia_ and i_ are from the struct iattr and struct inode -- which makes it slightly easier to read chains like this:
if (!IS_ERR(cookie) && path->dentry->d_inode->i_op->put_link)
path->dentry->d_inode->i_op->put_link(path->dentry, nd, cookie);
(Really. fs/namei.c, lines 821 and 822 in my source.)
It avoids accidently using a local variable when you meant to use the member (which the m is short for) variable of the object.
private String name;
private String mName;
public void setName(String name) {
name = name; //wrong, just set the parameter variable to itself
this.name = name; //ok, but has 'this.' which isn't a problem, but some people don't like it
mName = name; //simples
}
m for member variables, s for statics. It's a common naming convention. But like neutrino I don't use it very much. If you use a modern IDE, the syntax color-coding gives you the same information (actually more, because it works whether the original coder followed the naming convention or not).
I use the m prefix to define global variables for the class instance. I don't know why, but when I started and looked over other android code, it was like that.

Categories

Resources