java - 一个 native 方法可以从另一个 native 方法调用吗?

标签 java java-native-interface deprecated function-call finalize

我有一个 Java 类,其中包含某些 native 方法声明。它包含对 Finalize 方法中的 detroy() 的调用,该方法现已弃用。作为最终确定的替代方案,我使用了 try-with-resources 来实现 AutoCloseable。然而问题是,必须在我的 JSQ 类中重写的 AutoCloseable 提供的 close() 方法与我的代码中已定义的现有 native close 方法相冲突。如果我能找到一个可以调用 destroy 的替代位置,那么这应该足以作为解决方案。因此,我尝试从 native close() 调用 destroy(),这将是使用 shdl 的最后一点。这可能/允许/推荐吗?我无法选择删除或更改 native close(),这就是为什么我尝试从 native close 调用销毁。

JSQL.java

class JSQ implements AutoCloseable{
    protected long shdl;
    protected JSQ() { log("JSQ constructor"); }
    protected JSQ(String stmt, boolean isd)
        throws DhSQLException
    {
        // calls a set of native methods
        set_shdl();
        setstmt(stmt, shdl);
        setd(isd, shdl);
        prep(shdl);
    }

    // to be removed
    public void finalize()
    {
        destroy(shdl);
    }

    // alternative to finalize
    @Override
    public void close()
    {
        destroy();
    }

    protected void open()
    {
        parOpen (shdl);
    }

    private native void set_shdl() throws DhSQLException;
    private native void setstmt(String s, long shdl) throws DhSQLException;
    private native void setd(boolean b, long shdl);
    private native void prep(long shdl) throws DhSQLException;
    private native void destroy(long shdl);

    protected native void parOpen(long shdl);
    // following method is called from sub-classes of JSQ
    // super.close(shdl);
    protected native void close(long shdl);


    protected void execute() throws DhSQLException
    {
        parExec(shdl);
    }

    protected native void parExec(long shdl);
}

JSQ.cxx

#define SQ ((sq_stsm_t *)(shdl))

JNIEXPORT void JNICALL Java_com_project_package_JSQ_set_shdl
(JNIEnv *env, jobject obj_This)
{
    jclass cls;
    jmethodID mid;
    cls = (env)->GetObjectClass (obj_This);
    mid = (env)->GetMethodID (hThis,"set_JSQ_shdl","(J)V");

    status_t status;
    // memory allocation
    sq_stsm_t * S = new sq_stsm_t(status);
    if(status)
    {
        if (S) { delete S; }
        return;
    }
    // I understand that we're attempting to call a Java method from a native method.
    // But which method is it calling?
    // Also, are we converting S from sq_stms_t type to jlong?
    (env)->CallVoidMethod (obj_This,mid,(jlong) S);
    return;
}

JNIEXPORT void JNICALL Java_com_project_package_JSQ_setstmt
(JNIEnv *env, jobject, jstring jstmt, jlong shdl)
{
    status_t status;

    // cstmt is obtained using jstmt
    status = SQ->SetStmt(cstmt);
    return;
}

JNIEXPORT void JNICALL Java_com_project_package_JSQ_destroy
(JNIEnv *, jobject, jlong shdl)
{
    delete SQ;
}

JNIEXPORT void JNICALL Java_com_project_package_JSQ_close
(JNIEnv *env, jobject, jstring jstmt, jlong shdl)
{
    status_t status;
    status = SQ->CloseSQ();

    // Java_com_project_package_JSQ_destroy(shdl);    ?
    //destroy(shdl);    ?
    return;
}

Java_com_project_package_JSQ_destroy(shdl); ?

销毁(shdl); ?

或任何其他替代方案可以达到删除 Finalize() 并找到合适的销毁位置的目的?

最佳答案

实际上允许从一个 native 方法调用另一个 native 方法。至少,当我这样做时,我没有收到任何错误或警告。但调用必须包含任何 native 方法所期望的完整函数名称 - 即 Java_com_project_package_JSQ_destroy 且参数应包括:

  1. JNI 环境
  2. jobject 对象
  3. 方法期望的参数。在这种情况下,shdl

因此,调用必须如下所示:

Java_com_project_package_JSQ_destroy(env, <jobject_object_name>, shdl);

它应该调用 destroy 方法。然而,它并没有真正遵循 Java native 接口(interface)所服务的目的,Java native 接口(interface)是一个用于允许 Java 代码调用其他语言(此处为 C++)编写的 native 应用程序和库并被 native 应用程序和库调用的层。

关于java - 一个 native 方法可以从另一个 native 方法调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58077664/

相关文章:

c - 错误C4996:如何解决“GetVersionExa”弃用问题

swift - 如何在 Swift 5.0 中使用 withUnsafeBytes() 和 outputStream.write() 消除警告

java - WireMock 可以回放来自多个域的请求吗?

java - java中的客户端Web服务——代理认证

android - 无法加载库 libopencv_java.so

android - 通过在 qt 中从 C++ JNI 发送字符串在 Android 中显示 Toast

java - JNI中从tomcat调用类的问题

java - 避免嵌套 if 语句

java - 为什么 Java 集合中的 contains()/indexOf() 使用 o.equals(e) 而不是 e.equals(o)?

java - 已弃用的 org.jboss.resteasy.spi 异常的替代品是什么?