通过JACOB阅读JAVA中的BSTR

通过JACOB阅读JAVA中的BSTR,java,vb.net,com,jacob,Java,Vb.net,Com,Jacob,我试图通过JAVA接口中的COM对象访问设备 具体要求(如制造商所述)为: 姓名:ScanUSB 参数:[out]变量*序列号 用法:SerialNumber是指向包含BSTR数组的变量的指针 确切的调用并不重要,但我需要通过Java接口向它提供一个BSTR数组。COM界面的VB演示只需使用命令lm_Co1.ScanUSB(snNum),将Dim snNum作为Object=Nothing。然后,snNum中的项目将显示在下拉菜单中 我正试图和雅各布一起做这件事,因为我在沟通方面运气最好。这或多

我试图通过JAVA接口中的COM对象访问设备

具体要求(如制造商所述)为:

姓名:ScanUSB

参数:[out]变量*序列号

用法:SerialNumber是指向包含BSTR数组的变量的指针

确切的调用并不重要,但我需要通过Java接口向它提供一个BSTR数组。COM界面的VB演示只需使用命令
lm_Co1.ScanUSB(snNum)
,将
Dim snNum作为Object=Nothing
。然后,snNum中的项目将显示在下拉菜单中

我正试图和雅各布一起做这件事,因为我在沟通方面运气最好。这或多或少就是我正在使用的:

import com.jacob.com.Variant;
import com.jacob.com.Dispatch;

public class JunoReader {
  public JunoReader() {
    Dispatch oOphirLink = new Dispatch("clsid:{--the id of the device here--}");
    Variant snNum = new Variant();
    Variant testing = Dispatch.call(oOphirLink,"ScanUSB", snNum);
    println(testing);
    }
}
当我运行这个程序时,所有的东西都可以正常编译,我可以确认我正在与设备通信,但是我得到的只是我输入的空变量

我的问题是:如何通过JAVA接口将BSTR数组提供给COM对象


谢谢

所以,一个月零空闲时间之后,我对自己的问题有了一个答案,答案是“使用Python”

Python允许用户通过
comtypes
模块访问COM对象,只需一个命令:

from comtypes.client import CreateObject
target_guid = CreateObject("{TARGET-COM-CLSID-HERE}")
这允许python与COM对象进行通信,因此没有Java给我带来的麻烦。单行:
target\u guid.ScanUSB()
生成的
(u'717610',)
,是目标设备的序列号。请注意,Python读取COM对象生成的Unicode没有问题

第二个技巧涉及Python的COM服务器,由Win32 COM模块生成。因为COM服务器可以注册到Windows,所以我不必担心dll的位置。我只需要clsid。为了构建python COM服务器,我按照“服务器端COM和python快速入门”的说明进行了操作。那么这一切看起来是什么样的呢

Python代码:

class OphirPyCOM:

    _reg_clsid_ = "{PYTHON-COM-CLSID-HERE}"
    _reg_desc_ = "Python COM server"
    _reg_progid_ = "Python COM server"
    _public_methods_ = [    'Hello', 
                            'ConnectOphir', 
                            'ScanUSB', """More methods here"""
                            ]
    _public_attrs_ = ["""Some public attributes"""]
    _readonly_attrs_ = ["""some read-only attributes"""]

    def __init__(self):
        """some variables declared here"""

    def Hello(self, who):
        """Verifies a connection"""
        return "{PYTHON-COM-CLSID-HERE}" + str(who) 

    def ConnectOphir(self,clsid):
        """Connects to the target COM Object"""
        from comtypes.client import CreateObject
        self.target_guid = CreateObject(clsid)
        return "OphirLMMeasurement object created."

    def ScanUSB(self):
        """Communicates with the target device"""
        self.connected_inst = self.target_guid.ScanUSB()
        for i in range(0,len(self.connected_inst)):
            self.inst_list.append(str(self.connected_inst[i]))
        return self.inst_list

if __name__ == "__main__":
    # use 'python com.py' to register the COM server
    # use 'python com.py --unregister' to unregister it
    print "Registering COM server..."
    import win32com.server.register
    win32com.server.register.UseCommandLine(OphirPyCOM)
我们可以用命令行运行它并注册它。然后,我们将这些值与JACOB一起转移到Java:

import com.jacob.com.Variant;
import com.jacob.com.Dispatch;

public class JunoReader {

  String pyClsid = "{PYTHON-COM-CLSID-HERE}"; // This is where your python COM clsid goes
  String opClsid = "{TARGET-COM-CLSID-HERE}"; // This is where your ultimate target clsid goes 

  public JunoReader() {
    _pyClsid = "clsid:" + pyClsid
    // This finds the COM object location:
    Dispatch oOphirLink = new Dispatch(_pyClsid);  
  }

  public String HandShake() {
    String _talkBack = "is connected.";
    Variant _handShake = Dispatch.call(oOphirLink,"Hello",_talkBack); // I am trying to look for the Juno...
    return (_handShake.toString());
  }

  public String ConnectOphir() {
    Variant _connectOphir = Dispatch.call(oOphirLink,"ConnectOphir", opClsid); // Connect to the target COM object
    return (_connectOphir.toString());
  }

  public String ScanUSB() {
    Variant _serialNumberList = Dispatch.call(oOphirLink,"ScanUSB"); // This scans the USB ports for devices
    return (_serialNumberList.toString());
  }
}
调用
JunoReader.ScanUSB()
会产生:
717610
,与预期完全相同。通过实现制造商dll的后续方法,我可以将此设备中的数据读取到Java小程序中。问题解决了

警告:每次更改源文件时,您可能需要注销Python COM,然后使用不同的clsid重新注册。Java很难建立到更新代码的连接,除非每次更改文件时都使用新的clsid

为什么我要花这么多时间来打字?因为大多数关于将本机数据类型读入Java的建议都涉及JNI和JNA的某些版本。我花了几个星期的时间试图编译教程,但没有取得任何进展。另一方面,我昨天想到了这种方法,现在可以通过Java与我的设备进行通信。PythonCOM服务器提供了一种简单、直接的方式,将Java与本机应用程序连接起来。没有
未满足的链接错误
s,没有
找不到库
s,没有
类路径
JAVA_HOME
问题。我不需要学习C或C++,所有的Python教程都是经过描述的,没有必要的修改。p> 总之,如果您在将本机数据类型读入Java时遇到困难,只需设置一个Python COM服务器,让Python的动态类型为您完成这项工作