在一般应用中,我们可能会经常碰到这样一种情况,提供的dll是C#的,然后我们希望封装成Java的jar包发布,而且访问这个jar包的频率非常高。
这里,我们一般可能提供两种解决方案,一种就是使用C#封装原来的C#的dll,以WebService的方式提供,然后使用Java来调用这个WebService服务,最终将Java打包成jar包提供应用。另外一种方案就是先使用C++来封装这个C#类库,然后Java通过JNI来调用C++,前面的C++就必须和Java的方法在一定程度上保持一致。由于访问jar包频率很高,所以建议使用第二种方案。
那么在实际操作中,如果使用Java调用C++,并且C++调用C#呢。
首先说一下Java调用C++,使用的就是JNI(Java Native Interface)。操作步骤具体如下:
(1)打开Eclipse,什么版本无所谓,新建一个Java Project,比如这里取名叫做JNIDemo,这里假设这个JNIDemo项目存放在F:/JavaProject目录下面,然后在src下新建包名,比如com.killy,然后在killy下新建一个类,这里可以取名叫做JNIClass,并且在其内部添加一个Native方法和一个静态代码块,这个静态代码块是用来加载C++这个类的具体代码如下:

import com.killy; 


public class JNIClass() { 

 //这里定义一个native方法,这个方法需要在C++中实现 

 public native String getDescription(double age,String name); 


 static { 

 System.load("CPlusPlus"); 

 } 


 public static void main(String[] args) { 

 JNIClass jniClass = new JNIClass(); 

 System.out.println(jniClass.getDescription()); 

 } 

}


,保存了这个方法之后,我们打开cmd,进入到F:/JavaProject/src/com/killy目录下,如何进入(依次使用命令
cd F:/JavaProject/src/com/killy
F: 即可进入),使用
javac JNIClass.java命令,这样在F:/JavaProject/com/killy目录下会生成一个JNIClass.class的文件,在此在cmd下敲击
cd ..
cd ..
这样就回到了F:/JavaProject/src目录下,这时候使用命令
javah -classpath F:/JavaProject/src com.killy.JNIClass
这样就在F:/JavaProject/src目录下生成了一个.h文件,这个.h文件的名字是按照包名加下划线加类名,这里.h文件的名字应该是com_killy_JNIClass.h,这个文件就是该Java类文件编译之后的C++头文件。
接下来,我们要做的工作就是在C++中去实现这个.h头文件中所示的方法。
首先打开VS2008,新建一个C++的控制台应用程序,在过程中选择类库,项目名称我们暂且叫做CPlusPlus([color=red]注意,这里的CPlusPlus就和前面Java代码中System.load("CPlusPlus")必须保持一致了[/color]),在这个项目下,我们新建一个CPlusPlus.cpp的文件,然后将前面F:/JavaProject/src下生成的.h文件拷贝到这个项目的源代码文件夹下(物理拷贝),然后在这个项目的头文件上右键,选择添加现有项,将该.h文件添

加进来,然后我们会在这个.h文件中看到如下代码 

/* 

 * Class: com_killy_JNIClass 

 * Method: testFunction 

 * Signature: ()Ljava/lang/String; 

 */ 

JNIEXPORT jstring JNICALL Java_com_killy_JNIClass_getDescription 

 (JNIEnv *, jobject,jdouble,jstring);


我们将上述代码拷贝到CPlusPlus.cpp文件中,并且将上述代码进行一定的修改,变成:

/* 

 * Class: com_killy_JNIClass 

 * Method: testFunction 

 * Signature: ()Ljava/lang/String; 

 */ 

JNIEXPORT jstring JNICALL Java_com_killy_JNIClass_getDescription 

 (JNIEnv *env, jobject jobj,jdouble jdou,jstring jstr) { 

}


并且我们在这个CPlusPlus.cpp文件的最前面加上:
#include "com_killy_JNIClass.h" //这里是将.h文件添加到CPlusPlus.cpp文件中,用来实现该.h对应的定义的方法,这个.h文件就类似Java中的接口文件。
在上述的方法体内添加:

jstring jstr = (env)->NewStringUTF("hello,this is C++"); 

return jstr;



上述工作做完之后,我们C++这一端的工作就做完了,我们将这个工程设置成Release模式,并且设置成动态库(.dll)的配置类型,具体设置是右键项目,然后选择属性之后,弹出的窗口最上方有一个配置选项,这里设置成Release,然后页面左侧选择配置属性下的常规,项目默认值下的配置类型选择动态库(.dll)。
这样保存之后,我们右键项目,选择重新生成,生成成功之后,我们就可以在项目的Release或者Debug目录下找到一个CPlusPlusLibrary.dll的文件,将该文件拷贝到一个path包含的路径下,可以考虑放到C:/Windows/System32或者JDKPath/bin目录下,然后再回到Eclipse端,运行JNIDemo下面的JNIClass,这样我们看到控制台中输出了
hello,this is C++。
这样,整个流程就处理完成了,如果需要在C++中调用C#,可以参考另外一篇帖子,C++调用C#类库dll【[color=olive]http://superkilly.iteye.com/blog/976675[/color]】
[color=red][注意:如果前面的CPlusPlusLibrary.dll文件你不想放到这些目录下,希望自己在path中新添加一个路径,然后将该dll放到该目录下,这时候,你需要重新启动eclipse,因为之后重新启动eclipse,eclipse才能够将新加入的path路径读入内存中,否则将找不到该dll文件。][/color]