android.view.View
public void getLocationOnScreen (int[] location)
Computes the coordinates of this view on the screen. The argument must be an array of two integers. After the method returns, the array contains the x and y location in that order.
#include "Box2D.h" #include <cstdio> // // 这是盒子和小盒子的一个简单例子模拟使用Box2D的. // 这里我们创造一个大地面箱子和一小动态 // 箱子. int main(int argc, char** argv) { B2_NOT_USED(argc); B2_NOT_USED(argv); // 定义世界的大小。 //如果钢体到达世界的边缘,但是它将会速度越来越慢直到休眠。 // 我们创建地面体。要创建它我们需要一个物体定义(body definition),通过物体定义我们来 //指定地面体的初始位置。 b2AABB worldAABB; worldAABB.lowerBound.Set(-100.0f, -100.0f); worldAABB.upperBound.Set(100.0f, 100.0f); // 定义重力向量 b2Vec2 gravity(0.0f, -10.0f); // 是否休眠 bool doSleep = true; // 建立一个世界对象. b2World world(worldAABB, gravity, doSleep); //我们创建地面体。要创建它我们需要定义一个静态刚体(body definition),通过物体定义我们来 //指定地面体的初始位置。 b2BodyDef groundBodyDef; groundBodyDef.position.Set(0.0f, -10.0f); //将物体定义传给世界对象来创建地面体。世界对象并不保存到物体定义的引用。地面体是作 //为静态物体(static body)创建的,静态物体之间并没有碰撞,它们是固定的。当一个物体具有零质量的 //时候 Box2D 就会确定它为静态物体,物体的默认质量是零,所以它们默认就是静态的 b2Body* groundBody = world.CreateBody(&groundBodyDef); // 我们创建一个地面的多边形定义。我们使用 SetAsBox 简捷地把地面多边形规定为一个盒子 //(矩形)形状,盒子的中点就位于父物体的原点上。 b2PolygonDef groundShapeDef; //SetAsBox 函数接收了半个宽度和半个高度,这样的话,地面盒就是 100 个单位宽(x 轴)以及 //20 个单位高(y 轴)。Box2D 已被调谐使用米,千克和秒来作单位, groundShapeDef.SetAsBox(50.0f, 10.0f); //我们在地面体上创建地面多边形,以完成地面体 groundBody->CreateShape(&groundShapeDef); // 现在我们已经有了一个地面体,我们可以使用同样的方法来创建一个动态物体。除了尺寸之外的主要 //区别是,我们必须为动态物体设置质量性质。 //首先我们用 CreateBody 创建物体 b2BodyDef bodyDef; //设置起始坐标 bodyDef.position.Set(0.0f, 14.0f); b2Body* body = world.CreateBody(&bodyDef); // 接下来我们创建并添加一个多边形形状到物体上。注意我们把密度设置为 1,默认的密度是 0。并 //且,形状的摩擦设置到了 0.3。形状添加好以后,我们就使用 SetMassFromShapes 方法来命令物体通 //过形状去计算其自身的质量。这暗示了你可以给单个物体添加一个以上的形状。如果质量计算结果为 0, //那么物体会变成真正的静态。物体默认的质量就是零 b2PolygonDef shapeDef; //动态刚体的大小 shapeDef.SetAsBox(1.0f, 1.0f); //密度,密度默认为0为0时判断为静态钢体 shapeDef.density = 1.0f; //摩擦力 shapeDef.friction = 0.3f; //创建刚体 body->CreateShape(&shapeDef); //我也可以通过这个函数设置位置和角度 //body->SetXForm(b2Vec2(0.0f,5.0f),0.3f); //以物体形状计算 body->SetMassFromShapes(); // Box2D 中有一些数学代码构成的积分器(integrator),积分器在离散的时间点上模拟物理方程,它将 // 与游戏动画循环一同运行。所以我们需要为 Box2D 选取一个时间步,通常来说游戏物理引擎需要至少 // 60Hz 的速度,也就是 1/60 的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调 // 整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样做)。直截 // 了当地,这个就是时间步: float32 timeStep = 1.0f / 60.0f; // Box2D 中还有约束求解器(constraint solver)。约束求解器用于解决模拟中的所有 // 约束,一次一个。单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍微耽误另 // 一个。要得到良好的解,我们需要迭代所有约束多次。建议的 Box2D 迭代次数是 10 次。你可以按自己 // 的喜好去调整这个数,但要记得它是速度与质量之间的平衡。更少的迭代会增加性能并降低精度,同样 // 地,更多的迭代会减少性能但提高模拟质量。这是我们选择的迭代次数: int32 iterations = 10; // 输出坐标以及角度 for (int32 i = 0; i < 60; ++i) { // 单个约束求解以1/60帧。每帧计算10次 world.Step(timeStep, iterations); // 得到动态刚体的坐标以及角度 b2Vec2 position = body->GetPosition(); float32 angle = body->GetAngle(); printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle); } // When the world destructor is called, all bodies and joints are freed. This can // create orphaned pointers, so be careful about your world management. system("pause"); return 0; }
-----------------
英文文档见android-ndk-r6b的documentation.html
属于Android Native Development Kit (NDK)的一部分
见
http://developer.android.com/sdk/ndk/index.html
翻译仅个人见解
-----------------
Android does not support System V IPCs, i.e. the facilities provided by the following standard Posix headers:
Android不支持系统五进程间通信。即以下标准Posix头文件提供的工具:(注:Posix是Unix可移植操作系统接口的简称,是一种操作系统的API标准,但不限于Unix)
<sys/sem.h> /* SysV semaphores 系统五信号量*/
<sys/shm.h> /* SysV shared memory segments 系统五内存段*/
<sys/msg.h> /* SysV message queues 系统五消息队列*/
<sys/ipc.h> /* General IPC definitions 通用进程间通信定义*/
The reason for this is due to the fact that, by design, they lead to global kernel resource leakage.
之所以要这样做,是因为这样的事实,设计上它们会导致全局内核资源泄漏。
For example, there is no way to automatically release a SysV semaphore allocated in the kernel when:
例如,没有一种方法自动地释放在内核中分配的系统五信号量,当:
- a buggy or malicious process exits
- 一个有缺陷或恶意的进程存在。
- a non-buggy and non-malicious process crashes or is explicitly killed.
- 一个无缺陷且无恶意的进程崩溃或显式地被杀掉。
Killing processes automatically to make room for new ones is an important part of Android's application lifecycle implementation. This means that, even assuming only non-buggy and non-malicious code, it is very likely that over time, the kernel global tables used to implement SysV IPCs will fill up.
自动杀掉进程以腾出空间给新的进程,是Android应用程序生命周期实现的重要部分。这意味着,即便假设只有无缺陷且无恶意的代码,还是非常可能在不久后,用于实现系统五IPC的内核全局表将被填满。
At that point, strange failures are likely to occur and prevent programs that use them to run properly until the next reboot of the system.
到那时,奇怪的失败有可能会发生,并且阻止使用它们的程序正常运行,直至下一次系统重启。
And we can't ignore potential malicious applications. As a proof of concept here is a simple exploit that you can run on a standard Linux box today:
而且,我们不可以忽略潜在的恶意应用程序。作为这个观点的证明,这里有一个简单的漏洞(注:这里应该理解为漏洞或溢出攻击),如今你可以运行它在一个标准Linux机器里:
--------------- cut here ------------------------
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define NUM_SEMAPHORES 32
#define MAX_FAILS 10
int main(void)
{
int counter = 0;
int fails = 0;
if (counter == IPC_PRIVATE)
counter++;
printf( "%d (NUM_SEMAPHORES=%d)\n", counter, NUM_SEMAPHORES);
for (;;) {
int ret = fork();
int status;
if (ret < 0) {
perror("fork:");
break;
}
if (ret == 0) {
/* in the child 在子进程中*/
ret = semget( (key_t)counter, NUM_SEMAPHORES, IPC_CREAT );
if (ret < 0) {
return errno;
}
return 0;
}
else {
/* in the parent 在父进程中*/
ret = wait(&status); //注:等待,直至其中一个子进程退出
if (ret < 0) {
perror("waitpid:");
break;
}
if (status != 0) {
status = WEXITSTATUS(status);
fprintf(stderr, "child %d FAIL at counter=%d: %d\n", ret,
counter, status);
if (++fails >= MAX_FAILS)
break;
}
}
counter++;
if ((counter % 1000) == 0) {
printf("%d\n", counter);
}
if (counter == IPC_PRIVATE)
counter++;
}
return 0;
}
--------------- cut here ------------------------
If you run it on a typical Linux distribution today, you'll discover that it will quickly fill up the kernel's table of unique key_t values, and that strange things will happen in some parts of the system, but not all.
今时今日如果你在一个典型的Linux分发版上运行这个程序,你将发现它很快用唯一的key_t值占满内核表,而且将会在系统的某些部分发生奇怪的事情,但不是全部。
(You can use the "ipcs -u" command to get a summary describing the kernel tables and their allocations)
(你可以使用ipcs -u命令获取一个描述内核表及其分配的概要)
(注:ipcs用于提供IPC设施的状态信息,-u表示summary,我在ubuntu上得到的有共享内存,信号量,消息三项)
For example, in our experience, anything program launched after that that calls strerror() will simply crash. The USB sub-system starts spoutting weird errors to the system console, etc...
例如,以我们的经验看,在发生这种泄漏之后,程序所做的任何事情,一旦其中调用了strerror()就会简单地崩溃。USB子系统开始不断输出奇怪的错误到系统控制台,等等……