读好书,交益友
分类: Java
2013-06-25 19:07:39
剑客一直说我写的blog属于阳春白雪,很少有人看懂,以后尽量向大家灌输一些基础知识。
c语言通过jvm环境可以调用java类,我以前的blog写过。http://blogger.org.cn/blog/more.asp?name=hongrui&id=25509
只是新的版本发生了一点变化,没有JDK1_1InitArgs的定义,详见bug,
不在需要调用JNI_GetDefaultJavaVMInitArgs。
先写java类,
import java.awt.*;
import java.awt.event.*;
public class MyApp2 extends Frame
{
public MyApp2()
{
super( "My Java App" );
add( new Label("Hello, world!") );
}
public static void main( String[] args )
{
MyApp2 frame = new MyApp2();
frame.addWindowListener( new WindowAdapter()
{
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.setSize(200,200);
frame.setVisible(true);
}
}
编译为jar后,运行java -cp ./app.jar MyApp2
调用的java的c程序
#include
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif
#define USER_CLASSPATH "." /* where Prog.class is */
#define MAIN_CLASS "MyApp2"
#pragma comment(lib,"jvm.lib")
int main()
{
JNIEnv *env;
JavaVM *jvm;
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
char classpath[1024];
JavaVMInitArgs vm_args;
JavaVMOption options[4];
/* disable JIT */
options[0].optionString = "-Djava.compiler=NONE";
/* user classes */
options[1].optionString = "-Djava.library.path=.";
/*native library path*/
options[2].optionString = "-Djava.class.path=D:\\idea\\gui\\out\\artifacts\\app\\app.jar";
/* print JNI-related messages */
//options[3].optionString = "-verbose:jni";
options[3].optionString = "-verbose";
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 4;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Note that in the Java 2 SDK, there is no longer any need to call
* JNI_GetDefaultJavaVMInitArgs.
*/
/* Append USER_CLASSPATH to the end of default system class path */
/* sprintf(classpath, "%s%c%s", */
/* vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); */
/* vm_args.classpath = classpath; */
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
if (res < 0){
fprintf(stderr,"ERROR creat JVM failed resultcode=%d\n",res);
exit(1);D:\Java\jdk1.7.0_03\jre\bin\client
}
cls = (*env)->FindClass(env, MAIN_CLASS);
if (cls == 0) {
fprintf(stderr, "Can't find Prog class\n");
exit(1);
}
mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
if (mid == 0) {
fprintf(stderr, "Can't find Prog.main\n");
exit(1);
}
jstr = (*env)->NewStringUTF(env, " from C!");
if (jstr == 0) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
args = (*env)->NewObjectArray(env, 1,
(*env)->FindClass(env, "java/lang/String"), jstr);
if (args == 0) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
fprintf(stderr,"calling java...\n");
(*env)->CallStaticVoidMethod(env, cls, mid, args);
fprintf(stderr,"returned from java. killing VM.\n");
(*jvm)->DestroyJavaVM(jvm);
}
然后把编译好的程序,放到D:\Java\jdk1.7.0_03\jre\bin\client目录下,只要是jvm.dll一个目录,然后运行就ok。
值得注意的是两个path:classpath 和 java.library.path
classpath是指向jar包的位置
java.library.path是非java类包的位置如(dll,so)
经常在LINUX下使用系统变量LD_LIBRARY_PATH来添加java.library.path
很少在vm arguments里添加-Djava.library.path= /usr/local/lib