2014-05-25 2 views
0

JNI를 사용하여 원시 C 메서드를 호출하지만 첫 번째 메서드 호출 후에 Java 프로그램이 종료되고 (종료 코드 0) 코드의 나머지 부분에 도달하지 않습니다.JNI 메서드 호출 후 Java 프로그램이 종료됩니다.

Exec.java :

package libs; 

public class Exec { 

    static { 
     System.load(System.getProperty("user.dir")+"/bin/"+"libexec.so"); 
    } 

    public static native int execv(String pExecPath, String[] pArgs); 
} 

Exec.c :

#include <jni.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <errno.h> 


JNIEXPORT jint JNICALL 
Java_libs_Exec_execv(JNIEnv * env, jclass clazz, jstring pExecPath, jobjectArray array) { 
const char* execPath = (*env)->GetStringUTFChars(env, pExecPath, NULL); 
(*env)->ReleaseStringUTFChars(env, pExecPath, NULL); 

printf("Execution path: %s\n", execPath); 

int stringCount = (int) (*env)->GetArrayLength(env, array); 
char * args[stringCount+1]; 
args[stringCount] = NULL; 

for (int i=0; i<stringCount; i++) { 
    jstring string = (jstring) (*env)->GetObjectArrayElement(env, array, i); 
    char * arg = (*env)->GetStringUTFChars(env, string, 0); 

    printf("Argument %i:\t%s\n", (i+1), arg); 

    args[i] = arg; 

    (*env)->ReleaseStringUTFChars(env, string, 0); 
} 



int result = execv(execPath, args); 

printf("Exit code: %i\n", result); 
perror(NULL); 

return result; 
} 

TestExec.java :

package test; 

import libs.Exec; 


public class TestExec extends Exec { 

    public static void main(String[] args) { 

     execv("/bin/ps", new String[]{"ps", "ax"}); 
     execv("/bin/ls", new String[]{"ls", "-la", "/home"}); 
} 
} 

콘솔 출력 :

여기

내 소스내가 자격이 도움을받을 수있는 충분한 정보를 준 희망

Execution path: /bin/ps 
Argument 1: ax 
Exit code: 0 

을 : 6,

PID TTY  STAT TIME COMMAND 
1 ?  Ss  0:00 /sbin/init 
[...] 
5532 ?  R  0:00 ps ax 

또한 다음과 같아야 내 C-방법에서 콘솔 출력을 누락하고 있습니다.

답변

1

물론입니다. execv()를 호출합니다. JVM을 'ps'프로그램으로 대체하면 끝납니다.

아직 문자를 가리키는 포인터를 가지고있는 동안에는 ReleaseStringUTFChars()를 호출 할 수 없습니다.

오류가 발생하지 않는 한 'execv()'를 호출 한 후 프로세스의 출력이 표시되지 않습니다.

정말 하시겠습니까?

+0

글쎄, 사실 execv()를 사용하여 새로운 자식 프로세스를 시작하려고하지만 여전히 그 출력을 볼 수있다. – Deviluc

+0

execv()가 현재 프로세스를 대체하는지 몰랐습니다. 나는 대신 fork()를 사용할 것이고, 그러면 나의 라이브러리가 메인 메소드를 필요로한다고 생각 하는가? – Deviluc

+0

시스템 호출을 사용하기 전에 시스템 호출 문서를 읽는 것이 좋습니다. 나는 이것에 대한 필요성을 보지 못했다. Runtime.exec()가 이미 존재합니다. – EJP