锁定老帖子 主题:java 如何调用com组件接口方法。
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-09-10
大家都知道com组件的接口方法是基于windows下开发的。要在java里调的话。就要用到JNI技术。JNI是Java Native Interface的缩写,JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。尤其是c++或是c写的com组件接口。 JNI(Java Native Interface)的书写步骤 一般分为以下: 1、 编写带有native声明的方法的java类 写个例子来说明,最常用的还是hello world 的例子吧。 class HelloWorld { static { public static void main(String[] args) { 注意:LoadLibrary中的DLL文件名称可以随便定.只要做好的动态链接库改名成这个字符串就可以了 如果你想将一个方法声明为本地方法的话,必须将方法声明为native方法,并且不能实现。 做好该步准备以后,用javac TestNative.java生成.class.检验语法. 语法检查通过以后,用javah HelloWorld 生成.h的C头文件. 然后打开VC++6.0,新建->; 工程 ->; win32 Dynamic-Link Library .在向导中选择空工程. 把刚才javah生成的那个头文件加入工程 .然后 文件->;新建->;textFile 自己做一个.c文件.实现自己的native函数.例子如下: 1 #include 4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) 备注:
在实际应用中比较麻烦是数据类型的转换。因为要解决java和C++数据类型互通的问题。比如java里的string 如何映射为c++里相应的字符。还希望大家一起讨论。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-09-11
听说过javacom
|
|
返回顶楼 | |
发表时间:2007-09-13
如果要用java调com,不要用jni,因为jni搞不定com的事件通知
选择一:商业用途建议用J-Integra for COM。 优点:稳定,使用简单 缺点:只有商业版,收费的,贵死。 取巧的办法:weblogic中带了这套工具,听说weblogic很多盗版的.... 例如以一个com中有add(int,int)的方法,并有一个事件通知。样例代码如下: public class ConnectPointComTest { static { System.setProperty("JINTEGRA_NATIVE_MODE", ""); System.setProperty("JINTEGRA_COINIT_VALUE", "2"); } public void run() { try { _IDispConnectEventsAdapter evt=new _IDispConnectEventsAdapter(); final DispConnect dcon = new DispConnect(); dcon.add_IDispConnectEventsListener(evt); dcon.add(14, 5); } catch (IOException e) { e.printStackTrace(); } } } dispConn开头的类用J-Integra for COM提供的工具生成的。 使用起来就象使用普通的java类一样的简单。 选择二: JACOB - Java COM Bridge 优点:开源,免费的,效果高 缺点:超过10个并发就死翘翘了,代码不好看。 同样是上面的那个com,样例代码: public void run() { Dispatch test = new Dispatch("MyCOM.Test"); MyCOMEvent myCOMEvent = new MyCOMEvent(); DispatchEvents de = new DispatchEvents(test, myCOMEvent); Dispatch.call(test, "Add",90,68); Variant ret = Dispatch.call(test, "Sum", 3, 6); de.safeRelease(); test.safeRelease(); } 可以看到jacob的调用方式,类似与我们通过反射方式获得实例的方法,然后在调用方法的过程。麻烦啊 选择三:Jacozoom 优点:使用方法和J-Integra for COM类似,一样的简单 缺点:和jacob一样的不稳定,仅仅是稍微好点,并发超过20个才崩溃,收费的。 样例代码懒得写了。 评价 没事就不要用java调com,再简单的代码也简单不错用c#调com,而且效率很有问题,调用10万次后计算出平均每次调用时间为1.7毫秒,这个效率实在太低了。 |
|
返回顶楼 | |
发表时间:2007-09-13
谁说jni搞不定事件通知了?搞不定你列得这几个方案怎么实现的?SWT怎么实现的?只是你不会用罢了。
|
|
返回顶楼 | |
发表时间:2007-09-13
rehte 写道 谁说jni搞不定事件通知了?搞不定你列得这几个方案怎么实现的?SWT怎么实现的?只是你不会用罢了。
好,请给个例子 |
|
返回顶楼 | |
发表时间:2007-09-13
给个什么例子?
给个实现JNI事件通知的例子? SWT的实现以及你列的都是使用JNI实现的 还有AWT/Swing的事件循环系统也是这样的 |
|
返回顶楼 | |
发表时间:2007-09-13
对,就是给个实现JNI事件通知的例子. 象楼主一样,象我一样,给出真实、运行过代码。别光说,但又拿不出证明。
顺便补充一下上面我的例子中其他语言调用COM的代码。以下代码可以看到C#调用COM的代码比java的简单多了,就算是不会的人也猜得出这个com其实就是通过add方法传入两个整数,然后在事件相应中吧两个两个整数的处理结果输出。属于异步调用过程,上面例子中的main和disp_result在分别在两个线程中执行。 结论还是:JAVA调COM太麻烦了 VC#2005测试代码 using System; using System.Collections.Generic; using System.Text; using sample3Lib; namespace CSClient { class Program { static void evtProcess(int rst) { Console.WriteLine(rst); } static void Main(string[] args) { DispConnectClass disp = new DispConnectClass(); disp.Result += new _IDispConnectEvents_ResultEventHandler(disp_Result); disp.Add(1, 2); } static void disp_Result(int nVal) { Console.WriteLine(nVal); } } } 顺便补充一下COM的IDL import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(B2584167-40E5-413A-85D3-056CC6AA4057), helpstring("IDispConnect 接口"), pointer_default(unique) ] interface IDispConnect : IUnknown{ [, helpstring("方法Add")] HRESULT Add([in] LONG n1, [in] LONG n2); }; [ object, uuid(E38136E3-E271-46F2-B460-CF43A2A5BC1D), dual, nonextensible, helpstring("IEvent2 接口"), pointer_default(unique) ] interface IEvent2 : IDispatch{ [id(1), helpstring("方法Multiply")] HRESULT Multiply([in] LONG n1, [in] LONG n2); }; [ uuid(35CE13A7-14A1-4493-A16A-FEBD4843AED2), version(1.0), helpstring("sample3 1.0 类型库") ] library sample3Lib { importlib("stdole2.tlb"); [ uuid(32A65970-38E7-47A8-A923-3C61F60D362C), helpstring("_IDispConnectEvents 接口") ] dispinterface _IDispConnectEvents { properties: methods: [id(1), helpstring("方法Result")] HRESULT Result([in] LONG nVal); }; [ uuid(85BC3789-164A-4BF0-A206-7833A832F6A8), helpstring("DispConnect Class") ] coclass DispConnect { [default] interface IDispConnect; [default, source] dispinterface _IDispConnectEvents; }; [ uuid(D58AF39C-DA5C-47E1-AB40-C86FC61A2F19), helpstring("_IEvent2Events 接口") ] dispinterface _IEvent2Events { properties: methods: [id(1), helpstring("方法Result")] HRESULT Result([in] LONG nVal); }; [ uuid(1DF179A6-4560-4364-8102-01F8713534C8), helpstring("Event2 Class") ] coclass Event2 { [default] interface IEvent2; [default, source] dispinterface _IEvent2Events; }; }; |
|
返回顶楼 | |
发表时间:2007-09-13
JAVA调COM太麻烦了,这个我承认啊。但我反驳的是你的jni不能搞定事件通知的论调。你自己举的解决java com的解决方案已经反驳了自己,我举的证据SWT/AWT/Swing的事件系统也是证据。
我没有义务向你提供任何证明代码,也没有必要去证明。如果你想弄明白,自己去学习它们的代码。 |
|
返回顶楼 | |
发表时间:2007-09-13
这帖子也就说了java如何调用本地native代码,和com一点边都搭不上.连IUnknown都没有出现
|
|
返回顶楼 | |
发表时间:2007-09-13
rehte 写道 JAVA调COM太麻烦了,这个我承认啊。但我反驳的是你的jni不能搞定事件通知的论调。你自己举的解决java com的解决方案已经反驳了自己,我举的证据SWT/AWT/Swing的事件系统也是证据。
我没有义务向你提供任何证明代码去,也没有必要去证明去。如果你想弄明白,自己去学习它们的代码去。 --! COM事件和SWT/AWT/Swing的事件系统原理类似,但在实现上差别太大了. 说实话,要白手起家把Java和com串起来,问题不在接口,而在于要用c写一堆莫名其妙的东西. |
|
返回顶楼 | |