web服务器和C++的应用程序服务器装在一个电脑上,请问jni java可以调C++的应用程序服务器中的函数吗?请给我举个例子,谢谢

解决方案 »

  1.   

    “应用程序服务器”是指什么?如果你说的是Out-of-Proc COM Server,那是可以的。C++能调用的,JNI就能调用。
      

  2.   

    如果是动态链接库封装的函数,JNI是能够调用的。
    但如果C++函数没有 编译+连接过的话,是调用不了的
      

  3.   

    那jni能调的dll动态库必须把要使用的c++函数和功能全都放进dll文件里面,不能用dll文件再调用外部的c++程序中的函数吗?
      

  4.   

    回楼主:
    是的,JVM不会帮你去连接C的*.obj的
      

  5.   

    可不可以在load路径时候dll地址写C++里面dll地址,这样dll可不可以调用c++里面的函数?
      

  6.   

    楼主是什么需求?
    如果你要调用C++的函数,你可以把这个函数事先做到DLL中就可以了
    JVM不提供运行时链接目标文件的功能。DLL对外只是一个API,你JNI调用接口对象即可。
      

  7.   

    我现在是这样,我需要java来调c++里面的一些函数来完成一个功能,所以用jni来调dll,我希望是dll不是来封装所有功能,而是封装一个函数,而这个函数来完成调c++其他函数完成我需要的功能
      

  8.   

    怎么写JNI你可以看看http://java.sun.com/docs/books/jni/html/start.html
    http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html
    c++的服务器这个概念太泛,TCP Server, COM Server, Corba Server, Webservice Server都可以叫服务器。你要先了解C++程序提供什么接口,然后写一个对应的客户端。如果是Corba/webservice, Java可以直接访问,不需要通过JNI. COM接口也用很多Java的封装,不需要自己再写JNI.
    http://www.eclipse.org/articles/article.php?file=Article-ActivexSupportInSwt/index.html
    ActiveX Support In SWT
    http://www.developer.com/java/ent/article.php/770221
    Access COM Via Java -- A Tutorial
      

  9.   

    Java代码: 
    //Demo.java import   java.util.*; 
    import   java.lang.*; 
    public   class   Demo   { 
      
      public   static   int   COUNT   =   8; 
      public   String   msg   =   "still "; 
      public   int   nmsg   =   9;   
      public   int[]   counts   =   new   int[5]; 
      public   Date   date;   
      
      public   Demo(){ 
      } 
      
      public   Demo(String   msg){ 
          System.out.println( " <init> : "   +   msg); 
          for(int   i=0;i <5;i++) 
            counts[i]=2*i+1; 
          this.msg   =   msg; 
          this.nmsg   =   10; 
      
    //       date   =   new   Date(); 
    //       date.setYear(2005); 
    //       date.setMonth(11); 
    //       date.setDate(25); 
      } 
      
      
      public   String   GetMessage(){ 
        System.out.println( "GetMessage: "   +   msg); 
        return   msg; 
      } 
      
      public   void   SetMessage(String   msg,   int   nmsg){ 
        this.msg   =   msg; 
        this.nmsg   =   nmsg; 
        System.out.println( "SetMessage: "   +   msg); 
        System.out.println( "nmsg: "   +   nmsg); 
        
      } 
      
      public   int[]   GetCounts(){                                     //就是这个方法调用有问题 
        System.out.println( "GetCounts: "   +   msg); 
        return   counts; 
      }   public   void   SetCounts(int[]   counts){ 
        System.out.println( "SetCounts: "   +   msg); 
        this.counts   =   counts;     
      } 
        public   void   throwExcp()   throws   IllegalAccessException   { 
            throw   new   IllegalAccessException( "exception   occur. "); 
        }   
        
        public     static   void   main(String[]   args) 
        { 
        Demo   d   =   new   Demo( "abc "); 
        int[]   count   =   new   int[5]; 
        for(int   i=0;i <5;i++) 
        count[i]=10*i; 
        d.SetCounts(count);                 //java中调用是可以的 
        for(int   i=0;i <5;i++) 
        System.out.println( "count[ "+i+ "]=   "+d.GetCounts()[i]);   
        d.show(); 
        } 

    C++代码: #include   "stdafx.h " 
    #include   <jni.h> 
    #include   <assert.h> 
    #pragma   comment(lib,   "jvm.lib ") int   main(int   argc,   char*   argv[]) 

      JavaVMOption   options[3]; 
      JNIEnv   *env   =   NULL; 
      JavaVM   *jvm   =   NULL; 
      JavaVMInitArgs   vm_args; 
      jclass   cls; 
      jmethodID   mid; 
      jfieldID   fid;   //   sets   System   Properties   specific   to   VM 
      options[0].optionString   =   "-Djava.compiler=NONE "; 
      options[1].optionString   =   "-Djava.class.path=.; "; 
      options[2].optionString   =   "-verbose:jni "; 
      vm_args.version   =   JNI_VERSION_1_2; 
      vm_args.nOptions   =   3; 
      vm_args.options   =   options; 
      vm_args.ignoreUnrecognized   =   JNI_TRUE; 
      
      jint   nRetStatus   =   JNI_CreateJavaVM(&jvm,   (void**)&env,   &vm_args); 
      assert(   JNI_ERR   !=   nRetStatus); 
      
      cls   =   env-> FindClass( "Demo "); 
      assert(   0   !=   cls); 
    ...........//中间省略其他的调用// 
    ...........//保留报错的方法调用// 
      
      //Call   Setcounts     就是这个方法调用出错了 
      const   jsize   len   =   5; 
      const   jsize   start   =   0; 
      
      jintArray   arrint   =   env-> NewIntArray(len); 
      
    jsize   j;                                                                                       // 
    /*   获取数组对象的元素个数   */                                               // 
    int   lenth   =   env-> GetArrayLength(arrint);                       //查看新建的jintarry 
    /*   获取数组中的所有元素   */                                                   //是否创建成功   
    elems   =   env->   GetIntArrayElements(arrint,   0);             // 
    for(j=0;   j <   lenth;   j++)                                                         // 
    printf( "ELEMENT   %d   IS   %d\n ",   j,   elems[j]);                   // 
    env-> ReleaseIntArrayElements(arrint,   elems,   0);         // 
      jint   pbuf[len]   =   {90,   91,   92,   93,   94};   env-> SetIntArrayRegion(arrint,   start,   len,   pbuf);                     //拷贝数组pbuf到arrint 
      
    /*   获取数组对象的元素个数   */                                               // 
    lenth   =   env-> GetArrayLength(arrint);                               // 
    /*   获取数组中的所有元素   */                                                   //查看拷贝是否成功 
    elems   =   env->   GetIntArrayElements(arrint,   0);             //结果是arrint中已成功 
    for(j=0;   j <   lenth;   j++)                                                         //拷贝为pbuf中的数值 
    printf( "ELEMENT   %d   IS   %d\n ",   j,   elems[j]);                   // 
    env-> ReleaseIntArrayElements(arrint,   elems,   0);         // 
      mid   =   env-> GetMethodID(cls,   "SetCounts ",   "([I)V ");   assert(0   !=   mid);   //   jclass   ocls   =   env   -> GetObjectClass(demo); 
    //   mid   =   env-> GetMethodID(ocls, "SetCounts ", "([I)V "); 
    //估计参数使用有问题 
      env-> CallObjectMethod(demo,   mid,   arrint);           //程序执行就是在这里出错鸟~_~! 
      
      
      elems   =   env-> GetIntArrayElements(arrint,   0); 
      env-> ReleaseIntArrayElements(arrint,   elems,   0); 
        //Call   GetCounts           得到数组值的方法调用是正常的   不过目前得到是在Java中初始的值 
      mid   =   env-> GetMethodID(cls,   "GetCounts ",   "()[I "); 
      assert(0   !=   mid); 
      jintArray   arrret   =   (jintArray)     env-> CallObjectMethod(demo,   mid); 
      jsize   nlen   =   env-> GetArrayLength(arrret); 
      elems   =   env-> GetIntArrayElements(arrret,   0); 
      for(i   =0   ;i   <   nlen;   i++) 
      { 
        printf( "Element   %d   is     %d\n ",   i,   *(elems+i)); 
      }   
      env-> ReleaseIntArrayElements(arrret,   elems,   0);   
      //UnLoad   JavaVM 
      jvm-> DestroyJavaVM();     printf( "结束! "); 
      return   0; 
    }