В настоящее время я запускаю это на ОС Raspbian - Debian.
У меня есть две отдельные программы, работающие в унисон.У меня есть c ++ 'engine' и интерфейс python 'gui'.Я знаю, что, вероятно, есть гораздо лучшая практика, но в данный момент они общаются через простые файлы.По сути, графический интерфейс Python записывает в файл cmd.sf
конкретный текст, а механизм затем декодирует тот же файл и выполняет все, что ему нужно.
Настройка довольно проста:
C ++ Engine:
Программа C ++ постоянно читает файл cmd.sf
и остается в бесконечном цикле внутри механизма, если контекстфайла -1
.В тот момент, когда файл изменяет движок, он должен проанализировать то, что в основном написано в графическом интерфейсе Python, и после успешного выполнения любого содержимого, которое подскажет движок, записывает обратно в файл -1
Python GUI
На стороне GUI это та же концепция, за исключением обратного.GUI также постоянно читает из файла cmd.sf
и не продолжает писать ту же или другую инструкцию, пока не узнает, что механизм C ++ выполнен с его предыдущей инструкцией.Таким образом, он по существу проверяет файл, чтобы убедиться, что это что-то, НО -1
Проблема заключается в том, что, если я первоначально установил cmd.sf
на -1
, механизм C ++ делает то, что ему нужно для успешного выполнения,постоянно читая и проверяя содержимое файла.Тем не менее, в тот момент, когда я инструктирую графический интерфейс для изменения содержимого файла, механизм C ++ зависает, выдает ошибку сегмента и прерывает работу.
Однако я нашел что-то, что работает, и я не могу на всю жизньиз меня выяснить, почему.Если бы я должен был открыть cmd.sf
в текстовом редакторе, таком как geany (я Raspbian) и изменить содержимое через редактор и сохранить его, это не вызовет ошибку segfault.Фактически механизм C ++ замечает изменение содержимого файла, выполняет инструкцию соответствующим образом и записывает -1
обратно в файл.Кажется, мне не нравится, когда я программно изменяю содержимое файла.
Вот фрагмент моего кода на python, который изменяет содержимое файла, он вложен в цикл:
scan_cmd = AllCommands.start_scan
# generate the key cmd packet for engine to start listening to incoming switches
#
# with open("../data/switches_debug.sf") as sw_file:
# switch_ids = [i.split(",")[0] for i in sw_file.readlines()]
# #print(switch_ids)
packet = CommandPacket(0xFFFFFF, scan_cmd)
content = ""
can_edit_file = False
while not can_edit_file:
with open("../data/cmd.sf", "r") as cmd_file:
try:
content = int(cmd_file.readlines()[0])
except ValueError:
# means gui has already written to file and is in the form of x,x,x,...,x
# 12345,67,8
# The beginning of this function should just check to see if
# file content IS NOT -1 in order to prevent engine and gui
# writing to the file at the same time
#
# So if GUI has written to file and in the
# form of csv, it is obviously not -1
#
# assign content a value that is not -1
content = 0
if content == -1:
can_edit_file = True
msg = "Begin Listening... [%s]" % packet.hex()
print(msg)
content = ','.join(str(x) for x in packet.plist)
# open as 'w' to overrite content of file
with open("../data/cmd.sf", "w") as cmd_file:
cmd_file.write(content)
print("Wrote [%s] to ../data/cmd.sf" % packet.hex())
Аналогично, это код C ++, который читает и проверяет, изменился ли файл:
Scribe Cher("../data/cmd.sf");
for (;;) {
std::cout << std::flush;
// cpu_timer tmr;
// loop forever and read from cmd.sf for instructions
// if file contents is != -1 instruction from GUI is set; read and execute
// upon successful instruction execution write '-1' to file
// read contents of cmd.sf file
bool file_is_ready = false;
int u = 0;
do{
Cher.ReadFile(); // custome object that actually does the reading
cmd_file = std::stoi(Cher.FileContents); // Cher.FileContents is std::string
//debugging section
if(u % 10000 == 0){
std::cout << std::flush;
fmt::printf("File Contents: {%s}\n", Cher.FileContents);
}
if(cmd_file != -1){
file_is_ready = true;
}
u++;
}while(!file_is_ready);
}
Экземпляр Cher объекта Scribe с классом-помощником, который управляет чтением / записью в файлы.После инициализации он устанавливает один важный член в классе, и это путь к файлу. Каждый «Писец» назначается одному файлу.
void Scribe::ReadFile(){
std::string file_contents;
std::vector<std::string> vstring;
this->File.close(); //in case the file is opened
if(!this->File.open(std::ios::in)){
throw std::ios::failure("Unable to open file.");
//std::cout << "Unable to Open" << std::endl;
}
this->File.clear();
this->File.seekg(0, std::ios_base::beg);
while(this->File >> file_contents){
std::cout << "infinite loop" << std::endl;
vstring.push_back(file_contents);
}
//for(auto &i: vstring){
// std::cout << i << std::endl;
//
this->FileContents = vstring[0];
this->File.close();
}
Вот пример выходного вывода stdout из терминала, когда язапустите это, изначально установив cmd.sf
в -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
File Contents: -1
Segmentation Fault //this is when I use the python gui to change file contents