Trong một chương trình Julia chạy trên Linux, tôi cần khởi chạy một hành động chuyên dụng khi cửa sổ giao diện điều khiển được thay đổi kích thước. Vậy làm thế nào trong Julia, tôi có thể chặn tín hiệu hệ thống SIGWINCH (thay đổi kích thước cửa sổ) và gắn vào nó một chức năng thực hiện hành động cần thiết?
Trong Ada, việc khai báo nó khá đơn giản:
protected Signalhandler is
procedure Handlewindowresizing;
pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
end Signalhandler;
GIẢI PHÁP NHIỆM VỤ DỰA TRÊN IDEA CỦA SCHEMER: Tôi cố gắng sử dụng Thư viện C để thực hiện giám sát gián đoạn SIGWINCH.
thư viện của tôi
void Winresize (void Sig_Handler());
thư viện của tôi
#include "myLibrary.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void Winresize(void sig_handler (void)) {
signal(SIGWINCH, sig_handler);
}
Biên soạn & chuẩn bị thư viện
gcc -c -Wall -fPIC myL Library.c
gcc-Shared -fPIC -o myL Library.so myL Library.o
Chương trình tại Julia sử dụng Thư viện C:
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
Chương trình Julia chạy đúng nhưng khi cửa sổ đầu cuối được thay đổi kích thước, một lỗi Phân đoạn (lõi bị đổ) được phát hành và chương trình được cho là đã thoát với mã: 139.
Vì vậy, câu hỏi là lỗi phân khúc này đến từ đâu? Từ mô hình biên soạn? Julia không có quyền kiểm soát việc thực thi mã trong phần bộ nhớ trong đó C quản lý giám sát tín hiệu?
Loại bỏ hoạt động println trong Sig_handler ngăn chặn lỗi phân đoạn:
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