我是一名 Java 开发人员。我有一些 C++ 代码来进行一些系统相关调用。这段代码是使用 GCC 在 Intel 32 位平台上编译的(我有 make 文件),它在基于 Intel 的常规 32 位 linux 机器上运行良好。现在我需要在 Marvell ARM 处理器上运行的 linux 操作系统上运行它。当我在 java 中加载共享对象时,出现以下错误。
无法打开共享对象文件:没有这样的文件或目录(可能的原因:无法在 ARM 位平台上加载 IA 32 位 .so)
请告诉我如何解决这个问题。我查看了 GCC 选项,我找到了一个指定架构的选项(-march=armv5),但我无法使用该选项进行编译。
提前致谢。
在Android中,是有图书馆之间的差异使用加载System.loadLibrary()Java和使用库加载dlopen()在本地代码?我可以直接通过标准方式调用动态加载库中的函数JNI,还是必须使用dlsym()并创建一堆存根来检索函数?
我使用以下代码在 JNI 中使用“ARGB_8888”配置创建位图(仅黑色/灰色图像)。但是当我在 Java 代码中转储位图的内容时,我只能看到配置,而看不到位图中的像素数据。
JNI代码
// Image Details
int imgWidth = 128;
int imgHeight = 128;
int numPix = imgWidth * imgHeight;
// Creaing Bitmap Config Class
jclass bmpCfgCls = env->FindClass("android/graphics/Bitmap$Config");
jmethodID bmpClsValueOfMid = env->GetStaticMethodID(bmpCfgCls, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
jobject jBmpCfg = env->CallStaticObjectMethod(bmpCfgCls, bmpClsValueOfMid, env->NewStringUTF("ARGB_8888"));
// Creating a Bitmap Class
jclass bmpCls = env->FindClass("android/graphics/Bitmap");
jmethodID createBitmapMid = env->GetStaticMethodID(bmpCls, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jBmpObj = env->CallStaticObjectMethod(bmpCls, createBitmapMid, imgWidth, imgHeight, jBmpCfg);
// Creating Pixel Data
int triplicateLen = numPix * 4;
char *tripPixData = (char*)malloc(triplicateLen); …Run Code Online (Sandbox Code Playgroud) 在 Mac 上运行 JNI 失败后,我决定尝试在 Windows 上运行。我编译了我的 DLL,并将其放入java.library.path.
现在.. Java 给了我这个错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\path\to\dll\TheDll.dll: This operation is only valid in the context of an app container
Run Code Online (Sandbox Code Playgroud)
此操作仅在应用容器上下文中有效
什么?我试过用谷歌搜索这个,但没有显示任何相关性。奇怪的是,它在 Mac 上运行得很好。
这是什么原因?
这个问题与这个问题及其答案有关:
在 Java 中 int.class 是否等于 Integer.class 或 Integer.TYPE?
由于 int.class 不等于 Integer.class 我怎样才能通过 JNI 在本机级别获得 int.class Class 或其他原始类型?我需要指向 int.class 而不是 Integer.class 的 jclass 对象。
我正在使用 android sdk 4.2.2 在 mac os 上创建 cocos2d-x 游戏(v. 3.4),但我也尝试了其他。我想让 NativeHelper 类从 C++ 调用一些原生的 android 东西。我使用本教程作为基础:http : //www.cocos2d-x.org/wiki/User_Tutorial-Integrate_AdMob 它正在工作,但我想使用带参数的 java 函数。并且出现错误:
02-13 09:33:20.690: W/dalvikvm(28873): 假方法描述符: (I;)V 02-13 09:33:20.690: E/JniHelper(28873): 找不到 showBanner 的静态方法 ID
这是java实现:
public static void showBanner(int position) {
final int _position = position;
_appActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(_appActivity != null){
if (!_appActivity.adView.isEnabled()){
_appActivity.adView.setEnabled(true);
}
if (_appActivity.adView.getVisibility() == View.INVISIBLE){
_appActivity.adView.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if(_position == 0){
adParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
}
else{
adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); …Run Code Online (Sandbox Code Playgroud) 我在fortran中有一个具有简单void RESET()功能的Fifp.dll,并尝试从我的Java代码中调用它。我做了一个简单的java测试类:
public class TestJni {
static {
System.loadLibrary("Fifp");
}
public native void RESET();
}
Run Code Online (Sandbox Code Playgroud)
我从中制作了一个.h文件,并对其进行了编译。我还制作了一个桥文件myBridge.c:
#include <stdio.h>
#include "TestJni.h"
extern void RESET();
JNIEXPORT void JNICALL Java_TestJni_RESET(JNIEnv *env, jobject obj) {
printf("Before DLL call\n");
RESET();
printf("After DLL call\n");
}
Run Code Online (Sandbox Code Playgroud)
现在,我无法编译它。这是我在Visual Studio x64命令提示符下尝试的命令:
> cl -I"C:\path\to\jdk\include\win32" -I"C:\path\to\jdk\include" myBridge.c
Run Code Online (Sandbox Code Playgroud)
并且还有一个-FeFifp.dll选项,它给了我相同的错误:
LNK2019:无法解析的外部符号RESET(和main)
那么我在做什么错呢?
是否可以指定要包含的外部dll?
我是否以正确的方式执行new TestJni().RESET()呼叫?
任何帮助表示赞赏...
我已经使用JNI成功执行了一个简单的程序,我知道JNI是什么但我想知道它在哪里实时使用以及为什么我们需要JNI而我们可以在java中做任何事情.
I have recently created and published an Android App bundle with compiled native libraries for all processors architectures. On most of devices everything is running ok. But on some of devices I can see this error in Crashlytics console Fatal Exception: java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.someapp-wAu5DoLmLvM_RVnbU1qsCg==/base.apk"],nativeLibraryDirectories=[/data/app/com.someapp-wAu5DoLmLvM_RVnbU1qsCg==/lib/arm64, /system/lib64]]] couldn't find "somemylib.so"
I am wondering - why this may happen. I have libs for x64 processors. This is happening only on some devices - but this crash is the most …
问题是我们可以缓存jclass并jmethodID跨不同的JNI方法调用吗?
尝试通过缓存jclass和jmethodID其他JNI方法调用创建某个特定类的对象时,遇到了一些奇怪的行为。
这是一个简单的示例:
public class Main {
static {
System.loadLibrary("test-crash");
}
public static void main(String args[]) throws InterruptedException {
Thread.sleep(20000);
doAnotherAction(doSomeAction());
}
private static native long doSomeAction();
private static native void doAnotherAction(long ptr);
}
public class MyClass {
public int a;
public MyClass(int a) {
if(a == 10){
throw new IllegalArgumentException("a == 10");
}
this.a = a;
}
}
Run Code Online (Sandbox Code Playgroud)
JNI函数所做的只是创建类的对象MyClass。该函数doSomeAction返回一个指向已缓存的jclass和的指针jmethodID。这是本机方法的实现:
struct test{
jclass mc; …Run Code Online (Sandbox Code Playgroud)