日期:2014-05-20  浏览次数:20812 次

使用jni时的进程通信问题
虽然在C板块也提了同样的问题,不过为了能让更多人看到,也希望java板块也有对c很熟的人能帮忙看一下。
我在写一个编辑器,图形部分是用java写的,但是是通过exe来启动的,就像eclispe一样。 
我希望在已经启动一个进程的情况下,再打开文件不新开进程,而是把参数(文件名)传给原来的进程,在原来的进程里打开文件。 
其实就像notepad++一样拉,新打开文件是作为tab的。 
但是我对c很不熟,请问这个该如何实现呢? 
这是我的代码 
C/C++ code
#include<jni.h>
#include<windows.h>
#include<string.h>
#include<stdio.h>
#define MAXDIR 256
#define TRUE 1
#define FALSE 0
 
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevInst, LPSTR lpCmd, int nShow) {
    typedef int boolean;
    JNIEnv *env;
    JavaVM *jvm;
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jclass stringClass;
    jobjectArray args;
     
    boolean first_open = TRUE;
     
    char dir[MAXDIR] = "";   
    

    char szDrive[_MAX_DRIVE];
    char szFolder[_MAX_DIR];
    char szFileName[_MAX_FNAME];
    char szExt[_MAX_EXT];
     
    SetLastError(NO_ERROR);
    CreateMutex(NULL, FALSE, "RuleEditorInstance");
    if (GetLastError() == ERROR_ALREADY_EXISTS)
        first_open = FALSE;
    
 
 #ifdef JNI_VERSION_1_6
    if (first_open) {
        JavaVMInitArgs vm_args;
        JavaVMOption options[2];
         
        char jvm_class_path[1024] = "-Djava.class.path=";
        char lib_path[256] = "-Djava.library.path=\"";
         
         
        GetModuleFileName(NULL,dir,MAXDIR);
        _splitpath(dir, szDrive, szFolder, szFileName, szExt);
        strcpy(dir, szDrive);
        strcat(dir, szFolder);
         
        strcat(jvm_class_path, dir);
        strcat(jvm_class_path, "bin;");
        strcat(jvm_class_path, dir);
        strcat(jvm_class_path, "lib\\org.eclipse.swt.win32.win32.x86_3.4.0.v3448f.jar;");
        options[0].optionString = jvm_class_path;
        
        strcat(lib_path, dir);
        strcat(lib_path, "lib\"");
        options[1].optionString = lib_path;     
        
        vm_args.version = 0x00010002;
        vm_args.options = options;
        vm_args.nOptions = 2;
        vm_args.ignoreUnrecognized = JNI_TRUE;
        /* Create the Java VM */
        res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
         
        if (res < 0) {
            fprintf(stderr, "Can't create Java VM\n");
            exit(1);
        }
        cls = (*env)->FindClass(env, "ch/ruleedit/RuleEditor");
        if (cls == NULL) {
            goto destroy;
        }
     
        mid = (*env)->GetStaticMethodID(env, cls, "main",
                                         "([Ljava/lang/String;)V");
        if (mid == NULL) {
            goto destroy;
        }
        //解析lpCmd,赋值给jstr
        jstr = (*env)->NewStringUTF(env, "");
        if (jstr == NULL) {
            goto destroy;
        }
        stringClass = (*env)->FindClass(env, "java/lang/String");
        args = (*env)->NewObjectArray(env, 1, stringClass, jstr);
        if (args == NULL) {
            goto destroy;
        }
        (*env)->CallStaticVoidMethod(env, cls, mid, args);
    } else {
        //解析lpCmd(是个文件名)
        //怎么发送消息给已经在运行的进程?
        //进程怎么接收到消息?
        //进程在收到消息得到文件名后,就可以调用(*env)->CallStaticVoidMethod();了
    }
     
 #else
     fprintf(stderr, "JNI Version Not Supported...\n");
     exit(1);
 #endif /* JNI_VERSION_1_2 */
 destroy:
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->ExceptionDescribe(env);
    }
    (*jvm)->DestroyJavaVM(jvm);
    return 0;
 }



我用CreateMutex已经能判断是不是新进程了,问题主要是在那个else里面。 
主要就是怎么取到文件名参数,之后的事情就是java来完成了。

------解决方案--------------------
探讨
引用:
恩,是的,我在c板块也发了同样的问题了,我也是c小白阿。谢谢呵呵。
http://topic.csdn.net/u/20081016/21/dc39620f-4179-4296-a00c-fc7eb89ba4e8.html