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.
Related
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 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);
I currently try to figure out how to access the Camera via OpenMAX in Android 4.0. The documentation is not sufficient for me so I currently struggle with how I can retrieve the correct XADataSource for the following call.
(*_engine)->CreateMediaRecorder(_engine,
&_mediaRecorder, //pRecorder
nullptr, //pAudioSrc
XADataSource *, //pImageVideoSrc
XADataSink *, //pDataSnk
XAuint32, // numInterfaces
const XAInterfaceID *, //pInterfaceIds
const XAboolean *, //pInterfaceRequired
);
And please spare me the just use Java-"answers".
This is basically a definition of XADataSource, taken from http://www.khronos.org/registry/omxal/specs/OpenMAX_AL_1_1_Specification.pdf
typedef struct XADataSource_ {
void * pLocator;
void * pFormat;
} XADataSource;
Fields include:
Field Description
pLocator Pointer to the specified data locator structure. This may point to any of the following structures.
XADataLocator_Address
XADataLocator_IODevice
XADataLocator_URI
XADataLocator_MediaObject
XADataLocator_Null
XADataLocator_ContentPipe
The first field of each of these structures includes the 32 bit locatorType field, which identifies
the locator type (see XA_DATALOCATOR definitions) and hence the structure pointed to.
Note: The available XA_DATALOCATOR definitions may be extended through an API extension.
pFormat A pointer to the specified format structure. This may point to any of the following structures.
XADataFormat_PCM (Deprecated)
XADataFormat_PCM_EX
XADataFormat_MIME
XADataFormat_RawImage
The first field of each of these structures includes the 32 bit formatType field, which identifies the
format type (XA_DATAFORMAT definitions) and hence the structure pointed to. pFormat is ignored
if pLocator is XADataLocator_IODevice
Sorry couldn't format it better, but I suggest to check that document anyway if you haven't already done that.
The implementation of android only supports CreateMediaPlayer
and play MP2T H264 AAC stream.
http://mobilepearls.com/labs/native-android-api/ndk/docs/openmaxal/
Can someone explain to me what the exact meanings of the three JniHandleOwnership enum values in Mono for Android are? What's the difference between them?
My apologies for not updating the class library documentation yet.
The Binding Android Types documentation states what the various JniHandleOwnership values mean in the Wrapping with Java.Lang.Object section.
Update based on comments:
JniHandleOwnership.DoNotTransfer should be used if nothing should be done with the handle parameter. This should always be used within connector methods.
JniHandleOwnership.TransferLocalRef should be used when you have a local reference (e.g. you called JNIEnv.CallObjectMethod(), which returns a local reference) and you want to pass ownership of the local reference to a wrapper.
JniHandleOwnership.TransferGlobalRef should be used when you have a global reference and you want to pass ownership of the global reference to a wrapper:
IntPtr grefFoo = JNIEnv.FindClass("Foo"); // FindClass() returns a gref
var Foo = Java.Lang.Object.GetObject<Java.Lang.Class>(grefFoo, JniHandleOwnership.TransferGlobalRef);
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.