Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Java调用Microsoft.Z3.dll中的Z3_get_version()_Java_Scala_Dll_Java Native Interface_Z3 - Fatal编程技术网

如何从Java调用Microsoft.Z3.dll中的Z3_get_version()

如何从Java调用Microsoft.Z3.dll中的Z3_get_version(),java,scala,dll,java-native-interface,z3,Java,Scala,Dll,Java Native Interface,Z3,Microsoft.Z3.dll在文件属性中描述为Z3托管dll Java可以加载DLL。它使用System.loadLibrary或System.load执行此操作,具体取决于程序员的首选项 如果Java设计器也创建DLL,则可以使用javah定义导入/导出声明。不幸的是,这不是我的情况。该DLL已由Microsoft创建为托管C#DLL 我需要一些帮助来获取C#声明,比如在中找到的C#声明,并对Java包/类进行原型设计,以使调用成功。(我确信DLL已加载) 为了方便起见,Microsoft

Microsoft.Z3.dll在文件属性中描述为Z3托管dll

Java可以加载DLL。它使用System.loadLibrary或System.load执行此操作,具体取决于程序员的首选项

如果Java设计器也创建DLL,则可以使用javah定义导入/导出声明。不幸的是,这不是我的情况。该DLL已由Microsoft创建为托管C#DLL

我需要一些帮助来获取C#声明,比如在中找到的C#声明,并对Java包/类进行原型设计,以使调用成功。(我确信DLL已加载)

为了方便起见,Microsoft在的第03042行定义了特定调用。任何示例代码都将不胜感激

我从服务器收到的错误是:

java.lang.UnsatisfiedLinkError: Microsoft.Z3.GetVersion(
    LMicrosoft/Z3$IntPtr;
    LMicrosoft/Z3$IntPtr;
    LMicrosoft/Z3$IntPtr;
    LMicrosoft/Z3$IntPtr;)V
at Microsoft.Z3.GetVersion(Native Method)
at Microsoft.Z3.z3VersionString(Z3.java:81)
at DatabaseXml.XmlTest(DatabaseXml.java:66)
at DatabaseXml.doGet(DatabaseXml.java:124)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

我曾希望DLL的托管版本与Java有一些本机兼容性。看来不是这样。因此,答案是生成一个新的DLL,该DLL实现与JNI兼容的调用协议,如中所述。在上找到了一些有用的教程

大部分C源代码都是从Scala^Z3中提取的,最终版本是:

#include "stdafx.h"
#include <jni.h>
#include "z3.h"
// #include "z3_api.h" (z3.h automatically includes z3_api.h)
#include "HelloWorld.h"

#ifdef __cplusplus
extern "C" {
#endif
    JNIEXPORT void JNICALL Java_example_jni_HelloWorld_getVersion (
        JNIEnv * env, 
        jclass cls, 
        jobject major, 
        jobject minor, 
        jobject buildNumber, 
        jobject revisionNumber
    ) {

        unsigned int cmaj, cmin, bn, rv;
        jclass ipc;
        jfieldID fid;

        Z3_get_version(&cmaj, &cmin, &bn, &rv);

        ipc = (env)->GetObjectClass(major);
        fid = (env)->GetFieldID(ipc, "value", "I");
        (env)->SetIntField(major, fid, (jint)cmaj);
        ipc = (env)->GetObjectClass(minor);
        fid = (env)->GetFieldID(ipc, "value", "I");
        (env)->SetIntField(minor, fid, (jint)cmin);
        ipc = (env)->GetObjectClass(buildNumber);
        fid = (env)->GetFieldID(ipc, "value", "I");
        (env)->SetIntField(buildNumber, fid, (jint)bn);
        ipc = (env)->GetObjectClass(revisionNumber);
        fid = (env)->GetFieldID(ipc, "value", "I");
        (env)->SetIntField(revisionNumber, fid, (jint)rv);
    }
#ifdef __cplusplus
}
#endif

示例代码假定您已将所有DLL从C:\Program Files(x86)\Microsoft Research\Z3-3.2\bin复制到工作目录,并且已将java.exe指向编译的java类所在的正确类路径。如果一切顺利,运行命令“javaexample.jni.HelloWorld”将输出响应:Z3.2(build0,rev.0)

Scala^Z3()用于将Z3集成到Scala中。由于Scala在JVM上运行,我认为使用Scala^Z3是一个更好的起点?谢谢。。。看起来他们已经做了腿部工作。我已经添加了回答以下问题所需的日志。上面的示例演示了单个调用的机制,并将有助于理解位于的源代码。非常感谢Philippe Suter实施剩余通话。
package example.jni;

public class HelloWorld {

    private static final String LIB_SEPARATOR = "\\";
    private static final String LIB_NAME = "Z3GetVersion_Release";
    private static final String LIB_EXT = ".dll";

    /** Placeholder class to ease JNI interaction. */
    public static class IntPtr {
        public int value;
    }

    // this is just to force class loading, and therefore library loading.
    public static void init() { }

    static {
        String curDir = System.getProperty("user.dir");
        try {
            System.load(curDir + LIB_SEPARATOR + LIB_NAME + LIB_EXT);
        } catch (UnsatisfiedLinkError e) {
            System.out.println("Library could not be found in directory:" + curDir );
        } catch (SecurityException e) {
            System.out.println("Security permissions prevented loading library from directory:" + curDir );
        }
    }


    /*private static void getVersion(IntPtr major, IntPtr minor, IntPtr buildNumber, IntPtr revisionNumber)
    {
        major.value=0;
        minor.value=0;
        buildNumber.value=0;
        revisionNumber.value=0;
    }*/   
    private static native void getVersion(IntPtr major, IntPtr minor, IntPtr buildNumber, IntPtr revisionNumber);

    public static String z3VersionString() {
        IntPtr major = new IntPtr();
        IntPtr minor = new IntPtr();
        IntPtr buildNumber = new IntPtr();
        IntPtr revisionNumber = new IntPtr();
        getVersion(major, minor, buildNumber, revisionNumber);
        return "Z3 " + major.value + "." + minor.value + " (build " + buildNumber.value + ", rev. " + revisionNumber.value + ")";
    }

    public static void main(String[] args) {
        System.out.println(z3VersionString());
    }
}