站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题JBulider中调用dll的问题!给分100!问题解决,就结贴!

JBulider中调用dll的问题!给分100!问题解决,就结贴!

摘要: JBulider中调用dll的问题!给分100!问题解决,就结贴!


我在Jbulider中调用dll,出现了问题,恳请各路英雄帮忙!

我建了一个类,里面包含了与dll对应的函数,如下:
package org.HLC.OA.montnets;

import java.lang.*;

public class mondem
{
public native int SetModemType(int ComNo,int ModemType);
public native int GetModemType(int ComNo);
public native int InitModem (int PortNo);
public native int SendMsg (int PortNo, String strHeader, String strMsg);
public native String[]ReadMsgEx (int PortNo);
public native int SetThreadMode(int Mode);

//public native int MonInitModem(String strDev,int num);
//public native int MonSendMsg(int Chno,String strHeader,String strMsg);
//public native String[] MonGetMsg(int Chno);
//public native int MonCloseModem();
static
{
try{
System.out.println("mondem here123!");
System.loadLibrary("mondem");
System.out.println("mondem here too!");
}catch (Exception e){
System.out.println("load Library error:"+e);
}
}
public static void main(String args[])
{
}
}

然后在另外的一个类中调用这些函数,如下:
package org.HLC.OA.montnets;

import java.lang.*;
public class MsgServer
{
private mondem MyMondem=null;
int rc=0;

public void MsgServer(){
System.out.println("here is Ok!");

}
public void Instance(){ //创建Mondem,并且开启线程模式
try{
MyMondem = new mondem();
System.out.println("it is here!!");
//MyMondem.SetModemType(0,0);
//int modemType=MyMondem.GetModemType(0);
//System.out.println("the Mondem type is ="+modemType);
rc = MyMondem.SetThreadMode(1);
System.out.println("设置线程模式");
if (rc == 0)
{
System.out.println("设置线程模式成功");
}
else
{
System.out.println("设置线程模式失败");
return;
}
}catch(Exception ex){
System.out.println("error in MsgServer:"+ex);
}
}


public boolean SendMsg(String tophone,String msg){
Instance();
if((rc=(MyMondem.InitModem(-1)))==0)//初始化短信猫
{
System.out.println("初始化成功");
rc = MyMondem.SendMsg( -1, tophone, msg); //发送一条信息
if (rc == 0)
{
System.out.println("提交成功, rc=" + rc);
return true;
}
}
return false;
}


public static void main(String tophone,String msg)
{
mondem Mytest =new mondem(); //创建一个 mondem 对象, 这个对象最大可以支持64个端口发送
int rc;

rc=Mytest.SetThreadMode(1); //开启线程模式
if(rc==0){
System.out.println("设置线程模式成功");
} else {
System.out.println("设置线程模式失败");
return;
}
if((rc=(Mytest.InitModem(-1)))==0)//初始化短信猫
{
System.out.println("初始化成功");
rc=Mytest.SendMsg(-1,tophone,msg); //发送一条信息
if(rc==0){
System.out.println("提交成功, rc="+rc);

while(true) //循环等待发送成功,并显示接收信息, Ctrl-C 退出循环
{
String [] s = Mytest.ReadMsgEx(-1);
if(s[0]=="-1") {
System.out.println("-无信息-----");
} else {
System.out.println(s[0]);
System.out.println(s[1]);
System.out.println(s[2]);
}
System.out.println("...."+ //显示各个端口的状态
Mytest.GetStatus(0)+
Mytest.GetStatus(1)+
Mytest.GetStatus(2)+
Mytest.GetStatus(3)+
Mytest.GetStatus(4)+
Mytest.GetStatus(5)+
Mytest.GetStatus(6)+
Mytest.GetStatus(7)+
"...."
);
try{Thread.sleep(5000);}catch(InterruptedException e){} //延时等待
}
} else {
System.out.println("提交错误, rc="+rc);
}
} else {
System.out.println("初始化错误!"+rc);
}
}
}


当我在jsp中调用
MsgServer MobileMsg=new MsgServer();
MobileMsg.Instance();
的时候,MyMondem = new mondem();部分倒是可以通过,并且loadLibrary也没出现异常,就是当继续往下走,到rc = MyMondem.SetThreadMode(1)时,就卡着不动了。
另外,我参考另外一篇帖子,把MonDem.dll设置到了lib/native路径下了,不知道为什么还不行?不能调用DLL中的函数?


你的MonDem.dll不是JNI规范的,不是所有的DLL都可以调用的,你要对它进行封装改造


把有native方法的前面,都加上static声明,再试试看




to ykzhujiang(朱朱):那个DLL是没有问题的,因为我使用命令行编译运行MsgServer是可以调用DLL的,可是我在JBuilder下却不行。

to hjt28(hjt) :我加了还是不行。

还是谢谢你们的答复!


看一下Web容器的日志


还是用jawin调用com组件比较方便


to ykzhujiang(朱朱):不好意思,我是新手,找到了Web容器的日志,但是没有找到我程序运行部分的有用信息。

to amozon() :呵呵,这个老兄说的倒是,可是我是使用别人给dll做的,也是没办法的办法。

大家再帮帮忙了,谢谢!


并且令我奇怪的是程序运行到rc=Mytest.SetThreadMode(1); 这里就死掉了,也不报异常,让我找错,都无从找起。


LZ是放在tomcat下跑的么?

那只有两个位置可以放:一个是Tomcat的bin 另一个是JDK的bin

别它位置

另外其他应用服务器位置类似


to crazycy(崔毅),我是在Tomcat下跑的,不过MonDem.dll已经放到E:/**/Tomcat/lib/native下了,不是是这个路径还是直接放到E:/**/Tomcat/lib下啊?

另外,我也参考http://community.csdn.net/Expert/topic/4998/4998098.xml?temp=.4273493这篇文章看了一下,感觉情况类似,可是我按照它的方法弄了下(主要是把DLL放到lib/native下),还是不成!

我怀疑是不是DLL本身的问题,运行System.loadLibrary("mondem")是正确的,而调用其中的函数就会出错,死掉了。


你在System.loadLibrary("")//就是加载dll那块 打印这样的语句:

System.out.println("java.library.path");//看看它提示你的位置是哪里就好了;

然后你把dll转移到提示的位置,看是否解决了你的问题。

呵呵,以我上次二次开发的短信猫,应该是这样的


dll也可以放在其他任意位置,不过在启动的时候要用-Djava.library.path=...来设置path


继续关注~


这些天出差了,没有来得及回复大家,感觉很对不住大家!! :(

呵呵,现在我的问题终于解决了,我发现并不是DLL没有LoadLibrary到的原因,而是因为我对开发商给的DLL使用不当造成的(可是开发商也没告诉是这个原因,是偶经过查阅资料发现的,呵呵)

是这样的情况,我使用的mondem.java,这里面写着原生函数,和加载DLL的程序,在我提问的时候已经写明了。而开发商开发这个类的时候是把它包含在包montnets中了,再javac montnets.mondem.java,便生成了modem.java,然后再javah montnets.mondem,JNI便就会生成C/C++的头文件mondem.h。在C++中,mondem.cpp要包含这个头文件mondem.h,并且要实现mondem中的具体函数。mondem.cpp写成之后再进行联编等工作生成DLL文件。

问题就出现了,大家会发现在我的问题中,我把modem.java放在package org.HLC.OA.montnets中了,而DLL文件中默认的是montnets,这样就出现了我上面描述的问题。

下面贴出在http://community.csdn.net/Expert/topic/4998/4998098.xml?temp=4.395694E-02
这个帖子中webfax() 对问题的回答:
注:如果不是在当前工程的根目录下,则javah需要加路径,如:
例:TestDll 的Package为:com
首先在C:/j2sdk1.4.0-rc/bin>下新建目录:com
并拷贝TestDll.class到C:/j2sdk1.4.0-rc/bin/com
其次在CMD下,执行
C:/j2sdk1.4.0-rc/bin>javah com.TestDll,
在C:/j2sdk1.4.0-rc/bin下生成com_TestDll.h(结构为package_classname)
最后com_TestDll.h加入到DLL中去,生成新的DLL
我的解决的办法就是从这里得到灵感的:)

另外贴一篇关于JNI的文章,写得不错:
http://www.pconline.com.cn/pcedu/empolder/gj/java/0506/642328.html

呵呵,谢谢上边回帖的兄弟们!!



嘿嘿,我的承诺是“问题解决,就结贴!”为了大家在以后的工作中避免这样的错误,我决定帖子在留两天,嘿嘿,也算是大家共同学习吧!嘿嘿!

两天后,就把分分了!!!


↑返回目录
前一篇: Java怎样将图片转换成byte[ ]
后一篇: 10个对象有属性一起提交怎么保存数据库,用JDBC