2016-06-01 15 views
1

Gegeben eine Funktion wie exec, wie rufe ich es von lua ffi mit einer unbekannten Anzahl von Argumenten.Verwenden von luajit ffi zum Konvertieren variabler Argumente in ein char * const [] für execvp

Der Funktionsprototyp Wesen:

int execv(const char *path, char *const argv[]); 

heißt

function myexecv(...) 
    local arg = { ... } 
    local carg = ffi.new("char *const[?]", #arg) 
    for i = 1, #arg do 
     carg[i-1] = arg[i] 
    end 
    return ffi.C.execv(carg[0], carg) 
end 

Was nicht funktioniert.

Ich dachte, es könnte einen kurzen Weg der Initialisierung oder Schaffung etwas geben, das ich in argv übergeben kann. Wie mache ich das?

Antwort

1

Ich denke, ich habe es herausgefunden und es scheint zu funktionieren.

Ich schaute auf eine andere Bibliothek und fand einen anderen Weg, ffi.new aufzurufen und das etwas zu erweitern. Auch wegen des Typs konnte man eine Zeichenkette nicht direkt konvertieren, also erstelle ich sie zuerst als normales const char *. Und übergeben Sie die Länge + 1 (um null zu beenden). Übergeben Sie dann arg als Initialisierer. Dann recast es auf den richtigen Typ vor dem Aufruf der realen execv.

function myexecv(...) 
    local arg = {...} 
    arg = ffi.new("const char*[?]", #arg+1, arg) 
    arg = ffi.cast("char *const*", arg) 
    return ffi.C.execv(arg[0], arg) 
end 

Nun, das obige hat irgendwann funktioniert. Aber hörte auf zu arbeiten. Ich habe immer wieder "Bad Address" -Fehler bekommen. Es scheint, dass der Kopiervorgang für ffi.new nicht wie erwartet funktioniert hat. Also habe ich den Code in den folgenden geändert und das funktioniert zuverlässig.

function myexecv(...) 
    local arg = {...} 
    local argv = ffi.new("const char*[?]", #arg+1, arg) 
    argv[#arg] = nil 
    return ffi.C.execv(argv[0], argv) 
end 
1

Ohne Neufassung:

local ffi = require"ffi" 
ffi.cdef"int execv(const char*path, const char*const argv[]);" 

local function myexecv(...) 
    local arg = {...} 
    arg = ffi.new("const char*[?]", #arg+1, arg) 
    return ffi.C.execv(arg[0], arg) 
end 

myexecv("/bin/ls", "-l")