通过JACOB阅读JAVA中的BSTR
我试图通过JAVA接口中的COM对象访问设备 具体要求(如制造商所述)为: 姓名:ScanUSB 参数:[out]变量*序列号 用法:SerialNumber是指向包含BSTR数组的变量的指针 确切的调用并不重要,但我需要通过Java接口向它提供一个BSTR数组。COM界面的VB演示只需使用命令通过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中的项目将显示在下拉菜单中 我正试图和雅各布一起做这件事,因为我在沟通方面运气最好。这或多
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的动态类型为您完成这项工作