Dalam program Julia yang berjalan di Linux, saya harus meluncurkan tindakan khusus ketika jendela konsol diubah ukurannya. Jadi bagaimana di Julia, dapatkah saya mencegat sinyal sistem SIGWINCH (mengubah ukuran jendela) dan melampirkan padanya sebuah fungsi yang melakukan tindakan yang diperlukan?
Dalam Ada agak mudah untuk menyatakannya:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
SOLUSI TENTATIF BERDASARKAN IDEA OF SCHEMER: Saya mencoba menggunakan Perpustakaan C yang melakukan pemantauan gangguan SIGWINCH.
myLibrary.h
void Winresize (void Sig_Handler());
myLibrary.c
#include "myLibrary.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void Winresize(void sig_handler (void)) {
signal(SIGWINCH, sig_handler);
}
Kompilasi & persiapan Perpustakaan
gcc -c -Wall -fPIC myLibrary.c
gcc -bagi -fPIC -o myLibrary.so myLibrary.o
Program di Julia yang menggunakan C-Library:
function getc1()
ret = ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, true)
ret == 0 || error("unable to switch to raw mode")
c = read(stdin, UInt8)
ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, false)
c
end
function traitement() println(displaysize(stdout)); end
Mon_traitement_c = @cfunction(traitement, Cvoid, ())
ccall((:Winresize, "/home/Emile/programmation/Julia/myLibrary.so"), Cvoid, (Ptr{Cvoid},), Mon_traitement_c)
while true
println(getc1())
end
Program Julia berjalan dengan baik tetapi ketika jendela terminal diubah ukurannya kesalahan Segmentasi (core dumped) dikeluarkan dan program dikatakan keluar dengan kode: 139.
Jadi pertanyaannya adalah dari mana kesalahan segmentasi ini berasal? Dari model kompilasi? Julia tidak memiliki hak untuk mengontrol eksekusi kode di bagian memori di mana C mengelola pemantauan sinyal?
Menghapus operasi println di Sig_handler menekan kesalahan segmentasi:
curr_size = displaysize(stdout)
new_size = curr_size
function traitement() global new_size ; new_size = displaysize(stdout); return end
Mon_traitement_c = @cfunction(traitement, Cvoid, ())
ccall((:Winresize, "/home/Emile/programmation/Julia/myLibrary.so"), Cvoid, (Ptr{Cvoid},), Mon_traitement_c)
while true
global curr_size, new_size
if new_size != curr_size
curr_size = new_size
println(curr_size)
end
sleep(0.1)
end