我在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中的函数?

解决方案 »

  1.   

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

  2.   

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

  3.   

    to ykzhujiang(朱朱):那个DLL是没有问题的,因为我使用命令行编译运行MsgServer是可以调用DLL的,可是我在JBuilder下却不行。to hjt28(hjt) :我加了还是不行。还是谢谢你们的答复!
      

  4.   

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

  5.   

    to ykzhujiang(朱朱):不好意思,我是新手,找到了Web容器的日志,但是没有找到我程序运行部分的有用信息。to amozon() :呵呵,这个老兄说的倒是,可是我是使用别人给dll做的,也是没办法的办法。大家再帮帮忙了,谢谢!
      

  6.   

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

  7.   

    LZ是放在tomcat下跑的么?那只有两个位置可以放:一个是Tomcat的bin 另一个是JDK的bin别它位置另外其他应用服务器位置类似
      

  8.   

    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")是正确的,而调用其中的函数就会出错,死掉了。
      

  9.   

    你在System.loadLibrary("")//就是加载dll那块 打印这样的语句:System.out.println("java.library.path");//看看它提示你的位置是哪里就好了;然后你把dll转移到提示的位置,看是否解决了你的问题。呵呵,以我上次二次开发的短信猫,应该是这样的
      

  10.   

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

  11.   

    这些天出差了,没有来得及回复大家,感觉很对不住大家!!  :(呵呵,现在我的问题终于解决了,我发现并不是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呵呵,谢谢上边回帖的兄弟们!!
      

  12.   

    是生成 mondem.class 的头文件?还是生成 TestDll 的头文件?
    生成头文件后, mondem.cpp 怎么写才能实现各种方法
    然后在JBUILDER里面怎么用呢?谢谢!