小编Pav*_*l P的帖子

来自Android JNI中任何线程的FindClass

Android的JNI提示页面提到了这个FAQ:为什么FindClass找不到我的课程? 他们提到了多个解决方案,最后一个选项就是这个:

在某个地方缓存对ClassLoader对象的引用,并直接发出loadClass调用.这需要一些努力.

所以,我试图让它工作,似乎无论如何,这种方法根本不适合我.最后,我想到了如何使用ClassLoader但是如果从本机线程尝试未被触摸/加载的loadClass它将无法工作.本质上,当从本机线程调用时,它与行为中的env-> FindClass相同,但是对于已在应用程序中使用的类,它不会返回0.任何想法,如果我没有正确,或者无法从原生线程访问尚未使用/加载的类.






编辑:我会提供更多信息来解释我的意思.有常规的JNI env->FindClass(className),我写的另一个myFindClass(env, className)使用缓存ClassLoader->loadClass.

我试图从本机c/c ++访问的类是"com/noname/TestClient".在myFindClass里面我也使用它返回的env-> FindClass和log值:

jclass myFindClass(JNIEnv * env, const char* name)
{
    ...
    jclass c0 = env->FindClass(name);
    jclass c1 = (jclass)env->CallObjectMethod(ClassLoader,
        MID_loadClass, envNewStringUTF(name));
    dlog("myFindClass(\"%s\") => c0:%p, c1:%p, c0 and c1 are same: %d",
        name, c0, c1, env->IsSameObject(c0, c1));
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,我有这三种组合来解释这个问题.

1)

//inside JNI_OnLoad thread
myFindClass(env, "com/noname/TestClient");
...

//inside native thread created by pthread_create
myFindClass(env, "com/noname/TestClient");
Run Code Online (Sandbox Code Playgroud)

我得到这个logcat:

myFindClass("com/noname/TestClent")=> c0:0x41b64558,c1:0x41b64558,c0和c1相同:1
...
myFindClass("com/noname/TestClent")=> c0:0,c1:0x41b64558, c0和c1相同:0

2)

//inside JNI_OnLoad …
Run Code Online (Sandbox Code Playgroud)

c++ java-native-interface android

43
推荐指数
2
解决办法
3万
查看次数

Android:声音API(确定性,低延迟)

我正在审查各种Android声音API,我想知道我应该使用哪一种.我的目标是获得低延迟音频,或者至少是关于播放延迟的确定性行为.

我们遇到了很多问题,似乎Android声音API是废话,所以我正在探索各种可能性.

我们遇到的问题是sound_out.write(sound_samples);扬声器播放的声音和实际声音之间存在明显的延迟.通常它大约是300毫秒.问题是在所有设备上它都是不同的; 有些人没有这个问题,但大多数人都瘫痪了(但是,CS呼叫的延迟为零).这种荒谬的延迟最大的问题是,在某些设备上,这种延迟似乎是一些随机值(即它并不总是300毫秒).

我正在阅读有关OpenSL ES的内容,我想知道是否有人有过这方面的经验,或者它是相同的东西,但包装在不同的包中?

我更喜欢本机访问,但我不介意Java层间接,只要我能获得确定性行为:延迟必须是常量(对于给定的设备),或者我想要访问当前回放位置而不是猜测误差范围为±300 ms ......

编辑:
1.5年后,我尝试了多个Android手机,看看如何为实时语音通信获得最佳延迟.使用专业工具我测量了波浪路径的延迟.最佳结果超过100毫秒,大多数手机都在180毫秒范围内.有人有想法吗?

android android-ndk

35
推荐指数
1
解决办法
2万
查看次数

msys路径转换(或msys的cygpath?)

我需要将/DEF:c:\filepath\myLib.def"命令行选项从bash脚本传递给MS编译器/链接器.该路径是作为构建过程的一部分由bash脚本生成的.基本上,我的脚本的参数通行证是:

-DEF:/c/filepath/myLib.def
Run Code Online (Sandbox Code Playgroud)

MSYS路径转换无法正确处理它,因为它不了解/DEF:部分.如果我这样做的话

-DEF=/c/filepath/myLib.def
Run Code Online (Sandbox Code Playgroud)

但是ms工具不理解这个参数.简而言之,在MSYS bash中编写该参数的正确方法是什么,以便将其转换为正确的参数?

在cygwin上我可以使用cygpath,但没有相应的,因为msys的某些人认为它不需要(即使cygwin的脚本使用cygpath).

portability path msys mingw32 cygpath

32
推荐指数
4
解决办法
2万
查看次数

ldd相当于android

我有一个libTest.so,在某些设备上没有加载.logcat绝对没用.使用arm-linux-androideabi-readelf.exe -d libTest.so我能够看到libTest.so需要的所有必需的库.我将它们全部拉进我本地PC上的同一个文件夹中.

如何找出哪些符号丢失以及哪个库?我只有NDK的标准工具集(nm,readelf,objdump等).哪个工具以及如何使用它以便它解析我的libTest.so和所有依赖的libs并告诉我哪个符号阻止我的lib加载到目标设备上.

android android-ndk ldd readelf

21
推荐指数
3
解决办法
1万
查看次数

严格别名和内存对齐

我有性能关键代码,并且有一个巨大的函数,在函数开始时在堆栈上分配40个不同大小的数组.这些阵列中的大多数必须具有一定的对齐性(因为这些阵列是使用需要内存对齐的cpu指令(对于Intel和arm CPU)在链中的其他位置访问的.

由于某些版本的gcc无法正确对齐堆栈变量(特别是对于arm代码),或者甚至有时它表示目标体系结构的最大对齐小于我的代码实际请求的对齐,我别无选择,只能分配这些数组在堆栈上并手动对齐它们.

所以,对于每个数组,我需要做类似的事情才能使它正确对齐:

short history_[HIST_SIZE + 32];
short * history = (short*)((((uintptr_t)history_) + 31) & (~31));
Run Code Online (Sandbox Code Playgroud)

这样,history现在在32字节边界上对齐.对所有40个数组执行相同的操作非常繁琐,而且这部分代码实际上是cpu密集型的,我根本无法对每个数组执行相同的对齐技术(这种对齐混乱会使优化器和不同的寄存器分配混淆,从而减慢函数的使用时间,为了更好的解释,请参阅问题末尾的解释).

所以......显然,我只想做一次手动对齐,并假设这些数组一个接着一个.我还为这些数组添加了额外的填充,以便它们总是32个字节的倍数.那么,我只需在堆栈上创建一个jumbo char数组并将其转换为具有所有这些对齐数组的结构:

struct tmp
{
   short history[HIST_SIZE];
   short history2[2*HIST_SIZE];
   ...
   int energy[320];
   ...
};


char buf[sizeof(tmp) + 32];
tmp * X = (tmp*)((((uintptr_t)buf) + 31) & (~31));
Run Code Online (Sandbox Code Playgroud)

这样的事情.也许不是最优雅的,但它产生了非常好的结果,并且对生成的组件的手动检查证明生成的代码或多或少是足够的和可接受的.构建系统已更新为使用更新的GCC,突然我们开始在生成的数据中有一些工件(例如,即使在具有禁用的asm代码的纯C构建中,验证测试套件的输出也不再精确).调试问题花了很长时间,它似乎与别名规则和更新版本的GCC有关.

那么,我该怎么做呢?请不要浪费时间试图解释它不是标准的,不是可移植的,未定义的等等(我已经阅读过很多关于此的文章).此外,我无法改变代码(我可能会考虑修改GCC以解决问题,但不能重构代码)...基本上,我想要的是应用一些黑魔法咒语以便更新的GCC为这种类型的代码生成功能相同的代码而不禁用优化?

编辑:

  • 我在多个操作系统/编译器上使用了这个代码,但是当我切换到基于GCC 4.6的更新的NDK时开始出现问题.我用GCC 4.7得到了同样糟糕的结果(来自NDK r8d)
  • 我提到32字节对齐.如果它伤害了你的眼睛,用你喜欢的任何其他数字代替它,例如666,如果它有帮助.毫无疑问,大多数架构都不需要这种对齐.如果我在堆栈上对齐8KB的本地数组,则为16字节对齐松散15个字节,而对于32字节对齐,我松散31个字节.我希望我的意思很清楚.
  • 我说在性能关键代码中堆栈上有40个阵列.我可能还需要说它是一个运行良好的第三方旧代码,我不想搞砸它.没有必要说它是好还是坏,没有意义.
  • 此代码/函数具有经过良好测试和定义的行为.我们对该代码的要求具有确切的数量,例如它分配Xkb或RAM,使用Y kb的静态表,并且消耗多达Z kb的堆栈空间并且它不能改变,因为代码不会被改变.
  • 通过说"对齐混乱混淆优化器"我的意思是,如果我尝试单独对齐每个数组代码优化器为对齐代码分配额外的寄存器和性能关键代码部分突然没有足够的寄存器并开始垃圾堆栈而不是导致代码速度减慢.在ARM CPU上观察到这种行为(顺便说一句,我根本不担心英特尔).
  • 通过工件,我的意思是输出变为非bitexact,增加了一些噪音.要么是因为这种类型的别名问题,要么编译器中存在一些错误,最终导致函数输出错误.

    简而言之,问题的关键点......我如何分配随机数量的堆栈空间(使用char数组或者alloca,然后将指针对齐到该堆栈空间并重新解释这个内存块,因为某些结构具有一些定义良好的布局,只要结构本身正确对齐,我就会保证某些变量的对齐.我正在尝试使用各种方法来转换内存,我将大堆栈分配移动到一个单独的函数,仍然会导致输出错误和堆栈损坏,我我真的开始越来越多地认为这个巨大的功能会在gcc中遇到某种错误.这很奇怪,通过这样做,无论我尝试什么,我都无法完成这件事.顺便说一下,我禁用了所有需要任何对齐的优化,现在都是纯C风格的代码,我仍然得到不好的结果(非bitexact输出和偶尔的堆栈损坏崩溃).修复它的简单修复,我写而不是:

    char buf[sizeof(tmp) + 32];
    tmp * X = (tmp*)((((uintptr_t)buf) + 31) & (~31));
    
    Run Code Online (Sandbox Code Playgroud)

    这段代码:

    tmp …
    Run Code Online (Sandbox Code Playgroud)
  • c c++ casting type-punning

    17
    推荐指数
    2
    解决办法
    2405
    查看次数

    ARM到C调用约定,NEON寄存器保存

    有一个类似的帖子涵盖了常规寄存器.NEON寄存器怎么样?据我记得,函数调用必须保留上半部分或下半部分寄存器.我无法在任何地方找到这些信息,有人可以澄清一下吗?

    谢谢

    AAPCS,§5.1.1核心寄存器:

    • r0-r3是参数和临时寄存器; r0-r1也是结果寄存器
    • r4-r8是被调用者保存寄存器
    • r9可能是一个被调用者保存寄存器(在AAPCS的某些变体上它是一个特殊的寄存器)
    • r10-r11是被调用者保存寄存器
    • r12-r15是特殊寄存器

    AAPCS,§5.1.2.1VFP寄存器使用约定(VFP v2,v3和高级SIMD扩展):

    • 必须保留s16-s31(d8-d15,q4-q7)
    • s0-s15(d0-d7,q0-q3)d16-d31(q8-q15)不需要保留

    arm abi neon

    14
    推荐指数
    1
    解决办法
    5015
    查看次数

    在c/c ++中更改Android上的本机线程优先级

    疯狂地模糊pthread api的线程优先级不仅奇怪地难以理解,而且它在android上也不起作用.

    那么,有没有办法让我减少或增加线程的优先级?

    int currentPolicy;
    struct sched_param sched;
    status = pthread_getschedparam(pthread_self(), &currentPolicy, &sched);
    printf("sched.sched_priority:%d currentPolicy:%d", sched.sched_priority, currentPolicy);
    printf("priority min/max:%d/%d", sched_get_priority_min(currentPolicy), sched_get_priority_max(currentPolicy));
    
    Run Code Online (Sandbox Code Playgroud)

    输出:

    sched.sched_priority:0 currentPolicy:0

    priority min/max:0/0

    此外,无论我做什么,pthread_setschedparam总是为我返回一个错误(无效的参数).在我的代码中,我需要减少处理程序线程的优先级,以确保其他线程使用更多的CPU时间.或者,或者,我可以提升我的其他线程的线程优先级,我希望将其用作我的进程中其他线程的cpu.

    我有什么方法可以做到这一点吗?我只使用本机c ++代码.

    编辑:从这篇文章看起来像android的线程是某种轻量级的过程,并修改它们的优先级应该使用setpriority.它看起来该函数有效(getpriority之前和之后表示优先级已被修改).但是,我在我的应用程序中看不到预期的效果.

    c++ android pthreads android-ndk

    13
    推荐指数
    2
    解决办法
    1万
    查看次数

    Android构建系统,NEON和非NEON构建

    我想为armv6构建我的库,如果设备支持它,我会在运行时启用一些霓虹灯代码.霓虹灯代码使用霓虹内在函数,为了能够编译它,我必须启用armeabi-v7a,但这会影响常规的c代码(它在一些低端设备上会被破坏).

    因此,如果android构建系统没有过度干扰,我就不必提问,但似乎我没有办法为armv6编译一个文件而为arm7-neon编译另一个文件.

    任何人都可以提供任何线索,如果这是可行的吗?

    编辑
    在尝试回复和浪费互联网墨水之前,应该清楚这些是要点:
    1)只创建一个lib.
    2)使构建在armv6(pre-neon设备,例如armeabi)上运行.
    3)允许此构建还包含NEON代码(可以基于运行时cpu检测执行; cpu检测超出了问题的范围).
    4) NEON代码来自ac/cpp文件,使用neon intrinsics编写.

    省略这些要求的任何部分完全失去了问题的重点

    android arm neon android-ndk

    12
    推荐指数
    1
    解决办法
    2万
    查看次数

    iOS上的可恢复断言/断点,如带有MS编译器的__debugbreak()

    我正在尝试实现自定义资产宏(类似于assert.h所具有的),但我希望能够在获得并断言之后继续执行.

    例如,一个这样的ASSERT实现可以是:

    #define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0)))
    
    Run Code Online (Sandbox Code Playgroud)

    __debugbreak是Microsoft编译器中的一个内部函数,它插入了软件断点,相当于_asm int 3x86.对于iOS,有不同的方法来实现__debugbreak:

    • __asm__("int $3"); 对于x86.
    • __asm__("bkpt #0"); 对于常规手臂.
    • __asm__("brk #0"); for arm64
    • __builtin_trap()
    • raise(SIGTRAP)

    但是当我的断言命中时,所有这些都不能简单地跨过并继续我在使用visual studio时可以做的事情; 当我的iOS构建中的某些东西断言它在断言时卡住了,我别无选择,只能终止,我甚至无法手动移动指令指针并跳过断言.

    是否有可能在iOS上实现断言进入调试器并仍允许我继续执行的断言?

    c c++ debugging assert ios

    10
    推荐指数
    1
    解决办法
    490
    查看次数

    如何在 cmake 中删除或禁用目标

    我的项目使用第三方库项目。这个第三方库附带了他们自己的cmake项目文件,我们使用它。问题是他们的 cmake 项目有很多测试和示例可执行目标,在我们包含 cmake 之后,我们最终的 cmake 生成的 xcode 项目有所有这些不相关的测试和示例可执行目标。明显的方法是修改该 cmake 文件并删除/注释掉所有这些测试和示例可执行目标。但是,当我们更新库时,这将无法正常工作。我有什么选择,有没有办法包含 cmake 文件,然后禁用/删除 cmake 文件声明的一些目标?

    cmake

    10
    推荐指数
    1
    解决办法
    4213
    查看次数