[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]Java中,使用JNA调用Visa32.dll,控制频谱仪~~

上一篇:[备忘]SWT中删除Table行,TableEditor位置不刷新的问题,解决方法
下一篇:[转帖]JNI调用VISA的创建过程

添加日期:2012/8/21 16:57:58 快速返回   返回列表 阅读7596次
Java中,使用JNA调用Visa32.dll,控制频谱仪~~

C:\Program Files\Agilent\IO Libraries Suite\
有visa.chm,是方法和属性的说明。

首先,难倒在viOpen方法上。连不上频谱仪,什么都白搭啊~~

在visa.chm中,viOpen的格式如下:

viOpen(ViSession sesn, ViRsrc rsrcName, ViAccessMode accessMode, ViUInt32 timeout, ViPSession vi);


C:\Program Files\IVI Foundation\VISA\WinNT\include
visa.h
visatype.h
两个文件中,可以查看类型定义。visa.chm中也有说明。

ViSession、ViPSession,ViAccessMode 和ViUInt32,其实都是unsigned long
ViRsrc其实是char

所以,初始JNA代码如下:


package jna;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.LongByReference;

public class InstrumentWrong {

    public interface VISA32 extends Library {

        // VISA32 INSTANCE = (VISA32) Native.loadLibrary("VISA32",
        // VISA32.class);
        VISA32 INSTANCE = (VISA32) Native.loadLibrary(
                "C:\\WINDOWS\\system32\\VISA32.dll", VISA32.class);

        public static final long VI_NULL = 0;
        public static final long VI_SUCCESS = 0;

        public int viOpenDefaultRM(LongByReference session);

        public int viOpen(long viSession, String rsrcName, long accessMode,
                long timeout, LongByReference session);

        public int viClose(long vi);
    }

    LongByReference defaultSession;
    LongByReference vipSession;

    public boolean open(String deviceType, String ip) {
        VISA32 visa32 = VISA32.INSTANCE;

        defaultSession = new LongByReference(0);
        int result = visa32.viOpenDefaultRM(defaultSession);
        if (result != VISA32.VI_SUCCESS) {
            return false;
        }

        vipSession = new LongByReference(0);
        String cmd = "TCPIP0::<ip>::inst0::INSTR".replace("<ip>", ip);
        result = visa32.viOpen(defaultSession.getValue(), cmd, VISA32.VI_NULL,
                VISA32.VI_NULL, vipSession);
        if (result != VISA32.VI_SUCCESS) {
            System.out.println(result);
            return false;
        }
        return true;
    }

    /**
     * 关闭设备.
     * 
     * @return 成功返回true,失败返回false
     */
    public boolean close() {
        int result = VISA32.INSTANCE.viClose(vipSession.getValue());
        if (result != VISA32.VI_SUCCESS) {
            return false;
        }

        result = VISA32.INSTANCE.viClose(defaultSession.getValue());
        if (result != VISA32.VI_SUCCESS) {
            return false;
        }

        return true;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        InstrumentWrong device = new InstrumentWrong();
        boolean isOpen = device.open("xxx", "192.168.1.10");
        if (!isOpen) {
            System.out.println("open failed.");
            return;
        }

        device.close();

    }

}



运行,始终报错:
-1073807342
open failed.

在visa.h中搜错误号,可知定义是VI_ERROR_INV_RSRC_NAME。
是资源名字不正确~~~

搜了N久,以为是编码的问题,试过传递byte[]什么的,依然报此错误。
烦恼N久~~~

后经牛人指定,恍然大悟~~~

JNA的文档说明在此:
http://jna.java.net/javadoc/overview-summary.html#buffers
--------------------------
C Type            Native Representation                Java Type
long long, __int64    64-bit integer                    long
long            platform-dependent (32- or 64-bit integer)    NativeLong
-----------------------------

原来VISA中是32位的long,所以java中应该用NativeLong,而不是long~~~

修改后代码如下:


package jna;

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.LongByReference;

public class InstrumentRight {

    public interface VISA32 extends Library {

        // VISA32 INSTANCE = (VISA32) Native.loadLibrary("VISA32",
        // VISA32.class);
        VISA32 INSTANCE = (VISA32) Native.loadLibrary(
                "C:\\WINDOWS\\system32\\VISA32.dll", VISA32.class);

        public static final long VI_NULL = 0;
        public static final long VI_SUCCESS = 0;

        public int viOpenDefaultRM(LongByReference session);

        public int viOpen(NativeLong viSession, String rsrcName,
                NativeLong accessMode, NativeLong timeout,
                LongByReference session);

        public int viClose(NativeLong vi);

        public int viScanf(NativeLong vi, String readFmt, Object... args);

        public int viPrintf(NativeLong vi, String writeFmt, Object... args);
    }

    LongByReference defaultSession;
    LongByReference vipSession;

    public boolean open(String deviceType, String ip) {
        VISA32 visa32 = VISA32.INSTANCE;

        defaultSession = new LongByReference(0);
        int result = visa32.viOpenDefaultRM(defaultSession);
        if (result != VISA32.VI_SUCCESS) {
            return false;
        }

        vipSession = new LongByReference(0);
        String cmd = "TCPIP0::<ip>::inst0::INSTR".replace("<ip>", ip);
        NativeLong a = new NativeLong(defaultSession.getValue());
        NativeLong b = new NativeLong(0);
        result = visa32.viOpen(a, cmd, b, b, vipSession);
        if (result != VISA32.VI_SUCCESS) {
            System.out.println(result);
            return false;
        }
        return true;
    }

    /**
     * 关闭设备.
     * 
     * @return 成功返回true,失败返回false
     */
    public boolean close() {
        NativeLong a = new NativeLong(vipSession.getValue());
        int result = VISA32.INSTANCE.viClose(a);
        if (result != VISA32.VI_SUCCESS) {
            System.out.println(result);
            return false;
        }

        NativeLong b = new NativeLong(defaultSession.getValue());
        result = VISA32.INSTANCE.viClose(b);
        if (result != VISA32.VI_SUCCESS) {
            System.out.println(result);
            return false;
        }

        return true;
    }

    public boolean writeCmd(String cmdStr) {
        NativeLong a = new NativeLong(vipSession.getValue());
        int result = VISA32.INSTANCE.viPrintf(a, "%s\n", cmdStr);
        if (result != VISA32.VI_SUCCESS) {
            System.out.println(result);
            return false;
        }
        return true;
    }

    public String readResult() {
        NativeLong a = new NativeLong(vipSession.getValue());
        Memory mem = new Memory(200);
        int result = VISA32.INSTANCE.viScanf(a, "%t", mem);
        if (result != VISA32.VI_SUCCESS) {
            System.out.println(result);
            return null;
        }
        return mem.getString(0);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        InstrumentRight device = new InstrumentRight();
        boolean isOpen = device.open("xxx", "192.168.1.10");
        if (!isOpen) {
            System.out.println("open failed.");
            return;
        }

        // 查询设备名称
        device.writeCmd("*IDN?");

        // 读取返回值
        String s = device.readResult();
        System.out.println(s);

        device.close();

    }

}


执行,得到设备名称,OK啦~~哈
--------------------------
好像直接用int也可以~~~
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved