см. этот ответ также:
Это - относительно мягкий & корректное решение.
, Почему мой терминал невидим после уменьшения его и как я могу найти его?
заключение в кавычки:
Использование сочетание клавиш Super + W для показа графического обзора всех окон, включая терминал (терминалы); просто нажмите на тот, который Вы хотите поднять его.
(
Super
ключ =Win
ключ)
у меня была подобная проблема, которая происходит, когда Терминал разблокирован от средства запуска
, открытые окна часто не связаны с Терминальным средством запуска даже при том, что это использовалось для запуска их.
Другой неуклюжий и неэлегантный метод, который я использовал, перезагружает X-окна и следовательно Единицу путем ввода Высокого звука + Print Screen + K , чтобы уничтожить и перезапустить X-окна.
x-ref: окно терминала исчезает после того, как я минимизирую его
На самом деле, вы можете делать почти все, что хотите. В языке C (в отличие, например, от C ++) на функции в общих объектах ссылаются просто по их именам. Итак, чтобы найти - и, что наиболее важно, вызвать - нужную функцию, вам не нужна ее полная подпись. Вам нужно только его название! Это одновременно и преимущество, и недостаток - но такова природа выбранного вами языка.
Позвольте мне продемонстрировать, как это работает.
#include <dlfcn.h>
typedef void* (*arbitrary)();
// do not mix this with typedef void* (*arbitrary)(void); !!!
int main()
{
arbitrary my_function;
// Introduce already loaded functions to runtime linker's space
void* handle = dlopen(0,RTLD_NOW|RTLD_GLOBAL);
// Load the function to our pointer, which doesn't know how many arguments there sould be
*(void**)(&my_function) = dlsym(handle,"something");
// Call something via my_function
(void) my_function("I accept a string and an integer!\n",(int)(2*2));
return 0;
}
Фактически, вы можете вызывать любую функцию таким образом. Однако есть один недостаток. На самом деле вам нужно знать тип возвращаемого значения вашей функции во время компиляции . По умолчанию, если вы опускаете void * в этом typedef, int считается возвращаемым типом - и да, это правильный код C. Дело в том, что компилятор должен знать размер возвращаемого типа для правильной работы со стеком.
Вы можете обойти это с помощью уловок, например, заранее объявив несколько типов функций с разными размерами возвращаемых типов и затем выберите, в какой из них вы действительно собираетесь позвонить. Но более простое решение - потребовать от функций в вашем плагине всегда возвращать void * или int; фактический результат возвращается через указатели, заданные в качестве аргументов.
Вы должны убедиться, что вы всегда вызываете функцию с точным числом и типами аргументов, которые она должна принимать. Обратите внимание на разницу между разными целочисленными типами (лучше всего явно указать им аргументы).
То, что возвращает dlsym ()
, обычно является указателем на функцию, замаскированным под void *
. (Если вы спросите у него имя глобальной переменной, она также вернет вам указатель на эту глобальную переменную.)
Затем вы вызываете эту функцию так же, как и любой другой указатель на функцию:
int (*fun)(int, char *) = (int (*)(int, char *))dlsym(triangle, "function");
(*fun)(1, "abc"); # Old school - pre-C89 standard, but explicit
fun(1, "abc"); # New school - C89/C99 standard, but implicit
I я старая школа; Я предпочитаю явную нотацию, чтобы читатель знал, что «развлечение» - это указатель на функцию, без необходимости видеть ее объявление. В новой школьной нотации вы должны не забыть искать переменную ' fun
', прежде чем пытаться найти функцию с именем ' fun ()
'.
Обратите внимание, что вы не можете Постройте вызов функции динамически, как вы это делаете - или не в целом. Для этого потребуется гораздо больше работы. Вы должны заранее знать, что указатель функции ожидает в виде аргументов, что он возвращает и как все это интерпретировать.
Системы, которые управляют более динамическими вызовами функций, такие как Perl, имеют особые правила о том, как функции вызываемые и аргументы передаются и не вызывают (возможно, не могут вызывать) функции с произвольными подписями. Они могут вызывать только функции с заранее известными подписями. Один из механизмов (не используемый Perl) заключается в том, чтобы поместить аргументы в стек, а затем вызвать функцию, которая знает, как собирать значения из стека. Но даже если эта вызываемая функция манипулирует этими значениями, а затем вызывает произвольную другую функцию, эта вызываемая функция обеспечивает правильную последовательность вызова для произвольной другой функции.
Отражение в C сложно - очень сложно.