http://www.csdnjava.com/forum.php?mod=viewthread&tid=18746 --------------------------------------------- 安装VC++ 6.0 安装VISA。该软件主页为www.ni.com 具体下载地址应为:URL ftp://ftp.ni.com/support/visa/drivers/win32/3.2/visa320full.exe,下载前可能要免费注册。 其缺省安装目录是C:\Program Files\VISA。 建立c:\gpib目录,创建JNI本地接口类:JGpib.java ##c:\gpib\JGpib.java
package org.eleaf.jni.gpib; public class JGpib { public native int open(String gpibAddr);
public native int close();
public native String read();
public native int write(String cmdStr);
}
使用javac命令编译JGpib.java. c:\gpib>javac -d . .\JGpib.java
使用javah命令生成C++头文件: c:\gpib>javah -classpath . -d . org.eleaf.jni.gpib.JGpib
这是生成的头文件:org_eleaf_jni_gpib_JGpib.h ##c:\gpib\org_eleaf_jni_gpib_JGpib.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_eleaf_jni_gpib_JGpib */ #ifndef _Included_org_eleaf_jni_gpib_JGpib #define _Included_org_eleaf_jni_gpib_JGpib #ifdef __cplusplus extern "C" { #endif /* * Class: org_eleaf_jni_gpib_JGpib * Method: open * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_open (JNIEnv *, jobject, jstring); /* * Class: org_eleaf_jni_gpib_JGpib * Method: close * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_close (JNIEnv *, jobject); /* * Class: org_eleaf_jni_gpib_JGpib * Method: read * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_eleaf_jni_gpib_JGpib_read (JNIEnv *, jobject); /* * Class: org_eleaf_jni_gpib_JGpib * Method: write * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_write (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_eleaf_jni_gpib_JGpib */ #ifndef _Included_org_eleaf_jni_gpib_JGpib #define _Included_org_eleaf_jni_gpib_JGpib #ifdef __cplusplus extern "C" { #endif /* * Class: org_eleaf_jni_gpib_JGpib * Method: open * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_open (JNIEnv *, jobject, jstring); /* * Class: org_eleaf_jni_gpib_JGpib * Method: close * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_close (JNIEnv *, jobject); /* * Class: org_eleaf_jni_gpib_JGpib * Method: read * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_eleaf_jni_gpib_JGpib_read (JNIEnv *, jobject); /* * Class: org_eleaf_jni_gpib_JGpib * Method: write * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_write (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
启动VC++ 6.0: 1) 选择[new]->[projects](选择[Win32 Dynamic-Link Library],以测试程序中System.loadLibrary()方法中指定的dll库名gpib作为工程名)->[OK]->[An ampty DLL project]->[Finish]。
2) 选择[Tools]->[Options]->[Directories](添加目录%JAVA_HOME%\INCLUDE和%JAVA_HOME%\INCLUDE\WIN32)。在这些目录中包含JNI所需的头文件。
3) 将上面天生的org_eleaf_jni_gpib_JGpib.h拷贝到gpib工程文件夹中。 该工程文件夹的缺省位置为: C:\Program Files\Microsoft Visual Studio\MyProjects\gpib 然后把它添加到VC++中工程目录窗口中的[Head Files]条下。 然后是VC++中 VISA环境的设置,这在VISA的user guide文档visa.pdf中有具体说明。下面这段话是从该文档摘录过来的:
Microsoft Visual C++ Version 6.0 Compilers 1 Select Project > Settings from the menu and click the C/C++ tab.
2 Select Code Generation from the Category list box and select Multi-Threaded using DLL from the Use Run-Time Libraries list box. (VISA requires these definitions for Win32.) Click OK to close the dialog box.
3 Select Project > Settings from the menu. Click the Link tab and add visa32.lib to the Object/Library Modules list box. Optionally, you may add the library directly to your project file. Click OK to close the dialog box. 4 You may want to add the include files and library files search paths. They are set as follows: ?Select Tools > Options from the menu. ?Click the Directories tab to set the include file path. ?Select Include Files from the Show Directories For list box. ?Click at the bottom of the list box and type one of the following: C:\Program Files\VISA\win95\include or C:\Program Files\VISA\winnt\include.
5 Select Library Files from the Show Directories For list box.
6 Click at the bottom of the list box and type one of the following: C:\Program Files\VISA\win95\lib\msc or C:\Program Files\VISA\winnt\lib\msc
所有的环境设置都完成以后,就可以在VC++里编写cpp文件进行编译连接了: 点击工程目录窗口中的[Source Files]创建一个新的cpp文件,命名为org_eleaf_jni_gpib_JGpib.cpp: ##C:\Program Files\Microsoft Visual Studio\MyProjects\gpib\org_eleaf_jni_gpib_JGpib.cpp
#include <visa.h> #include <stdio.h> #include <string.h> #include "org_eleaf_jni_gpib_JGpib.h" //定义三个全局变量,供下面四个独立函数调用。 static ViSession defaultRM; static ViSession vi; static char buf[256] = {0}; //以下四个独立函数是按照上面的头文件里的函数定义创建的。 JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_open (JNIEnv *env, jobject obj, jstring jstr) { //将从java程序中传进来的字符串转化为C++中的字符串格式。 const char *str = env->GetStringUTFChars(jstr, 0); char cap[256]; strcpy(cap, str); /* 在VISA中,viOpen()、viClose()、viScanf()、viPrintf()等方法都会返回一个ViStatus类型的值,这个值对应C++中的int型,代表方法执行的结果。假如是正确,ViStatus返回为VI_SUCCESS,值为0。假如出错,则返回各种负值,如: -1073807299 VI_ERROR_INV_MASK -1073807298 VI_ERROR_IO -1073807297 VI_ERROR_INV_FMT 我们可以在C++程序中直接把这些ViStatus对象作为int型的值进行调用,如: printf("result=%d\n", VI_SUCCESS);将打印出: result=0 printf("result=%d\n", VI_ERROR_IO);将打印出: result=-1073807298 关于这部分,在VISA的API文档里面有具体先容,对于windows 2000,该文档的地址为: C:\Program Files\VISA\winnt\agvisa\visa.chm ViStatus的说明在该文档[目录]下的[VISA Library Information]下的[VISA Error Codes]条里。 */ ViStatus viss = viOpenDefaultRM (&defaultRM); ViStatus vis = viOpen(defaultRM, cap, VI_NULL, VI_NULL, &vi); return vis; }
JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_close (JNIEnv *env, jobject obj) { ViStatus viss = viClose(vi); ViStatus vis = viClose(defaultRM); return vis; } JNIEXPORT jstring JNICALL Java_org_eleaf_jni_gpib_JGpib_read (JNIEnv *env, jobject obj) { viScanf(vi, "%t", &buf); //将C++的字符串转换为java的字符串格式并返回。 return env->NewStringUTF(buf); }
JNIEXPORT jint JNICALL Java_org_eleaf_jni_gpib_JGpib_write (JNIEnv *env, jobject obj, jstring jstr) { const char *str = env->GetStringUTFChars(jstr, 0); char cap[256]; strcpy(cap, str); ViStatus vis = viPrintf(vi, cap); return vis; }
点击[Build]>[Compile org_eleaf_jni_gpib_JGpib.cpp]或按Ctrl + F7,编译该cpp文件。 检查一下下边的[Build]窗口,看是否有错误出现,假如没有错误,应该会出现如下的信息:
--------------------Configuration: gpib - Win32 Debug-------------------- Compiling... Skipping... (no relevant changes detected) org_eleaf_jni_gpib_JGpib.cpp org_eleaf_jni_gpib_JGpib.obj - 0 error(s), 0 warning(s)
假如有错误,一般可能是语法题目或环境设置不正确,请仔细更正,然后重新编译。 然后点击[Build]>[Build gpib.dll],天生动态链接库文件。 编译连接完成后,请将天生的gpib.dll文件拷贝到系统环境变量PATH中可以找到的任意位置,比如%JAVA_HOME%\bin;%TOMCAT_HOME%\bin等。 编写测试程序:Test.java ##c:\gpib\Test.java
package org.eleaf.jni.gpib; public class Test { //装载动态链接库gpib.dll. static { System.loadLibrary("gpib"); } public static void main(String[] args) { JGpib jg = new JGpib(); /* VISA可以连接电脑的GPIB/USB/Serial/COM/等端口。这里的ASRL1::INSTR字串表 示连接的是COM1端口,关于该字串的格式,在VISA的API文档里面有具体先容,对 于windows 2000,该文档的地址为: C:\Program Files\VISA\winnt\agvisa\visa.chm 字串格式的说明在该文档[目录]下的[VISA Functions]下的[viOpen]条里。 */ int i = jg.open("ASRL1::INSTR"); int j = jg.write("*RST\n"); int a = jg.write("*IDN?\n"); String s = jg.read(); System.out.println("s=" + s); int b = jg.close(); //封闭会话以后,尝试调用write()方法发送指令,预计返回错误信息,即变量c、d的值将为负数: int c = jg.write("*RST\n"); int d = jg.write("*IDN?\n"); System.out.println(i + ";" + j + ";" + a + ";" + b + ";" + c + ";" + d); } }
编译执行Test.java c:\gpib>javac -classpath . -d . Test.java c:\gpib>java -classpath . org.eleaf.jni.gpib.Test 0;0;0;0;-1073807346;-1073807346
前面四个值为0,代表ViStatus中的VI_SUCCESS,表示执行成功; 最后两个负数值-1073807346,对应ViStatus中的VI_ERROR_INV_OBJECT(The object reference is invalid. ),表明在viClose()方法执行以后,会话已被封闭,继续通过viPrintf()发送指令会发生错误。
|