我一直都这么问,但我从来没有得到过一个非常好的答案; 我认为,在写第一个"Hello World"之前,几乎所有程序员都遇到过"宏不应该使用宏","宏是邪恶的"这样的短语等等,我的问题是:为什么?有了新的C++ 11,这么多年后还有一个真正的选择吗?
简单的部分是关于宏#pragma,特定于平台和特定于编译器,并且大多数时候它们具有严重的缺陷,例如#pragma once在至少两种重要情况下容易出错:不同路径中的相同名称以及一些网络设置和文件系统.
但总的来说,宏的用法和替代品呢?
我正在进行的项目要求我编写跨平台程序实现的android部分.
构建了一组核心功能,并将其包含在我的应用程序中android-ndk.我发现在本机代码中发生的任何异常/崩溃只会在现在和最后再次报告.发生错误时,我会收到以下行为之一:
NullPointerException(通常在每个本机代码异常的相同位置,这是一个巨大的痛苦).通常会让我花费一段时间来尝试调试为什么Java代码抛出错误只是为了发现Java代码很好并且本机代码错误已被完全掩盖.我似乎无法找到任何方法来"隔离"我的代码以防止在本机代码中发生的错误.Try/catch语句被彻底忽略了.除了我的代码被指责为罪魁祸首之外,我甚至没有机会警告用户而不是发生错误.
有人可以帮我解决如何应对崩溃本机代码的情况吗?
java-native-interface android exception-handling nullpointerexception android-ndk
我用C/C++开发应用程序/程序.我更熟悉这两种语言,喜欢成为C++开发人员.我想知道如何创建一个包含所有C++代码的Java程序.
我的意思是,我想在Java类中包装我所有的C++代码(已经开发).但无能为力如何做到这一点.
请发布您在Java中集成C++的响应或方法/步骤.(使用JNI就是这样,但我无法在www上弄清楚如何使用它)
仅供参考,我使用Eclipse IDE进行开发.
我应该在项目工作区中包含哪些包和哪些包?
说我有以下Java代码:
public class Test {
public static int foo() {
throw new RuntimeException();
}
}
Run Code Online (Sandbox Code Playgroud)
以通常的方式加载本机库.本机库注册并缓存JVM或其他任何东西,然后,稍后执行此函数:
JNIEnv* sEnv; // initialised somewhere properly
void throwMeARiver() {
jclass c = sEnv->FindClass("Test");
jmethodID m = sEnv->GetStaticMethodID(c, "foo", "()I");
jint i = sEnv->CallStaticIntMethod(c, m);
printf("Got %d\n", (int)i);
}
Run Code Online (Sandbox Code Playgroud)
显然,sEnv-> CheckException()现在将返回JNI_TRUE,但是本机函数会打印出来的是什么?在Java中,抛出异常会使JVM停止执行它所在的方法,直到找到合适的处理程序,因此foo()的返回值是未定义的.所以我也未定义?
我找不到任何规格或任何其他说法,所以大概是i/is/undefined.与大多数JNI函数不同,在这种情况下,CallStaticIntMethod没有"正常"范围.
我现在正在尝试这个,但我主要是在问这个问题,看看某个地方是否存在强制行为.
我需要一个在 JNI 代码中实现的异常处理。我不擅长 jni,找不到任何好的例子。因此,请为此提供完整的示例。
这就是我正在做的:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
jint result = -1;
g_JavaVM = vm;
if (vm->GetEnv((void **) &envLocal, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
jclass clazz;
**clazz = envLocal->FindClass("com/graphics/myclass/MyClass");**
if (clazz == NULL)
__android_log_print(ANDROID_LOG_ERROR, "MyClass",
"clazz value is null");
g_clazz = (jclass) envLocal->NewGlobalRef(clazz);
// STEP 3/3 : Delete the no longer needed local reference
envLocal->DeleteLocalRef(clazz);
result = JNI_VERSION_1_6;
return result;
}
Run Code Online (Sandbox Code Playgroud)
现在我需要如果这个 MyClass 不可用(因为应用程序开发人员没有相应的 jar 文件),那么不应该有任何应用程序崩溃。当使用 System.LoadLibrary("libmyclass.so") 和这个 "com/graphics/myclass/MyClass" 类加载库时,将调用 JNI_OnLoad。
目前,如果此 jar 未包含在应用程序中,则会导致应用程序崩溃并出现以下异常
F/art …Run Code Online (Sandbox Code Playgroud) 我的项目使用捕获崩溃的模块并在android系统中发送.处理本机崩溃时,本机代码将执行某些操作,然后从JNI执行Java调用.它适用于Dalvik.但它在使用ART的5.0以上的Android版本中失败了.因为ART在本机信号处理期间阻止来自JNI的任何Java调用.它说ART信号处理使用备用信号堆栈,所以在信号处理过程中,不能调用java方法吗?还有其他方法吗?
流:
1.Java调用本机方法,但本机方法崩溃.
2.本机崩溃处理程序捕获信号以处理崩溃.
3.在崩溃处理过程中,调用JNI方法但失败了
12-31 20:36:02.516 7845-7957 A/art: art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI IsSameObject called with pending exception 'java.lang.StackOverflowError' thrown in...
in call to IsSameObject
stack=0x9fff8000-0x9fffa000 stackSize=1036KB
Run Code Online (Sandbox Code Playgroud)
参考:https://code.google.com/p/android/issues/detail?
id = 162663如果有人使用ART和/或Bionic可以调查一下,那就太好了.
java-native-interface android exception-handling native-code
假设我有一个这样的 Java 类:
public class Test
{
static { System.loadLibrary("test"); }
public native int foo();
}
Run Code Online (Sandbox Code Playgroud)
假设 foo() 方法正在执行一些 JNI 调用,并且其中一个调用失败(IE,抛出异常)。然后我想从 JNI 代码返回并在 Java 中抛出异常。例如:
jint Java_Test_foo(JNIEnv* env, jobject thiz)
{
jstring foobar = (*env)->NewStringUTF(env, "Hello from JNI !");
if(foobar == NULL) // Not enough memory. OutOfMemoryError is thrown
return NULL; // Return immediately to get exception thrown in Java
// Do other stuff
...
return some_computed_jint;
}
Run Code Online (Sandbox Code Playgroud)
问题是这return NULL不是一个吉特。例如,在 Android 中,我在编译时会收到此警告:
warning: return Makes Integer from Pointer …
我正在尝试在eclipse中的java应用程序中使用dll,但每当我尝试调用与该dll相关联的任何方法时,我都会遇到运行时异常.
dll存在于以下地址中,我在eclipse 中的运行/调试设置中传递了该地址:
-Djava.library.path="C:\Program Files\NPortAdminSuite\ipserial\lib\x86;${env_var:PATH}"
Run Code Online (Sandbox Code Playgroud)
码:
class Test {
public native int nsio_init();
public static void main(String[] args) {
System.loadLibrary("ipserial");
new Test().nsio_init(); //This part is throwing an exception
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: NPortConnection.nsio_init()I
at Test.nsio_init(Native Method)
at Test.main(Test.java:27)
Run Code Online (Sandbox Code Playgroud)
该命令dumpbin /exports "C:\Program Files\NPortAdminSuite\ipserial\lib\x86\IPSerial.dll"还返回我的方法名称,我试图从该DLL调用

谁能告诉我们如何解决这个问题?
android ×3
android-ndk ×3
exception ×3
java ×3
c++ ×2
eclipse ×2
c++11 ×1
dll ×1
jint ×1
native-code ×1