简体   繁体   中英

Shell commands to run Common Lisp from Visual Studio

I want to make a new process that runs a Common Lisp program with parameters given from my C# program. In other words, I'm looking for interoperability between those programs. Right now I'm using this code to open clisp in cmd :

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();

cmd.StandardInput.WriteLine("clisp");
cmd.StandardInput.WriteLine("(load " + '"' + "CargarNodos.lisp" + '"' + ")");
cmd.StandardInput.WriteLine("(cargar-cds)");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());

I can load my .lisp file, but the program crashes when I call the function "cargar-cds" (if I run directly the lisp function from cmd it works fine). I think the part of the .lisp that crashes is this code:

(SETQ NODOS () )

(defun cargar-cds()
(SETQ L (OPEN "adyacencias.txt" :IF-DOES-NOT-EXIST NIL))
(WHEN L
    (LOOP FOR LINEA = (READ-LINE L nil) WHILE LINEA DO
    (setq lst     (loop for i = 0 then (1+ j)
          as j = (position #\tab LINEA :start i)
          collect (subseq LINEA i j)
          while  j ))
    (formato-plano lst)
    (setq NODOS (append NODOS (list LISTAF))))
)
NODOS)

Visual Studio doesn't show me an error, even when the c# code posted is inside a try/catch, the application running only freezes

The error is thrown in another process, clisp , and so you cannot expect a try/catch in the calling environment to catch those errors. The freezing is probably because the underlying Lisp environment, which is defined to be interactive, enters the debugger. You might want to add -on-error exit (see https://clisp.sourceforge.io/impnotes/clisp.html ) to disable this behavior. Also, you could redirect the output/error of the process to the C# process's output stream. This should help you detect errors from the underlying process.

It runs fine,but the code I posted is missing an apostrophe: (SETQ NODOS '() ).

The apostrophe is superfluous here, both () and '() denote the same value.

the complete code is quite large, it calls another function, but I think the main problem is in the one posted, maybe because it reads a text file.

Your priority should be to be able to replicate the bug using only the clisp interpreter and/or trying to see why it behaves differently in both cases (from C# and directly). Maybe the relative pathname you are using is resolved to a file that is non-existent in different contexts.

It is however difficult to test your Lisp code: there seems to be other parts that are not detailed. For example, LISTAF is referenced only once, as well as other parts. If you could try to reformat the code to be exactly as the one which works (maybe remove comments) and provide a minimal example that works from within clisp but fails from C#, that could help us determine what is wrong.

There are a bunch of problems in the code. The first is that it is not formatted correctly. This makes it extra hard to find bugs.

(defun cargar-cds()

  ; L is undefined.
  ; Why use OPEN instead of WITH-OPEN-FILE ?
  (SETQ L (OPEN "adyacencias.txt" :IF-DOES-NOT-EXIST NIL))


  (WHEN L
    (LOOP FOR LINEA = (READ-LINE L nil) WHILE LINEA DO
    ;(PRINT LINEA)
    ;Separar datos de una fila


    ; the variable lst is undefined
          (setq lst (loop for i = 0 then (1+ j)
                          as j = (position #\tab LINEA :start i)
                          collect (subseq LINEA i j)
                          while  j))

    ;Darle formato (IDCd NombreCd Latitud Longitud (IDVecino1 Distancia1) ... 
          (IDVecinoN DistanciaN))
    (formato-plano lst)
    (setq NODOS (append NODOS (list LISTAF))))

  ; here your function is ending

  )    ; this closes the defun above

  ; commented out, but makes no sense, you probably wanted to close the stream L
    ;(CLOSE LINEA))

; dangling code follows. Why is it there?

NODOS)

The child process initiated by the c# code was longer than expected, due to the size of the data; the father process didn't give him the time needed to finish. The solution was waiting a moment before closing the process cmd.WaitForExit(1000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM