Есть ли способ во время выполнения команды не вызывать определенную функцию (закомментировать ее) в C (Linux)? - PullRequest
0 голосов
/ 16 апреля 2020

Я хочу указать во время выполнения, чтобы игнорировать вызов функции для функции (которая, конечно, определяется) внутри моего исполняемого файла. Пожалуйста, предложите некоторую методологию для того же самого на C языке Linux.

Ответы [ 2 ]

1 голос
/ 16 апреля 2020

Вероятно, лучшее, что вы можете сделать, это что-то вроде этого:

// Filename mycode.c

int main()
{
  // ...
  #ifndef SOME_MACRO
  someFUnction();
  #endif

  //...

}


int someFUnction()
{

 // does something

}

Чтобы исключить вызов функции в main, вам нужно скомпилировать с

gcc -DSOME_MACRO mycode.c

Если вы скомпилируете просто как

gcc mycode.c

, то вызов функции будет включен.

0 голосов
/ 16 апреля 2020

Вы не можете игнорировать вызовы функций во время выполнения, вы либо вызываете функцию, либо нет.

Но давайте предположим, ради этого ответа, что существует условие, при котором функция вызывается и при по крайней мере, другое условие, при котором функция не вызывается.

Вы можете сообщить программе эти условия несколькими способами, например, для каждой командной строки, изменения среды / файла и, возможно, длинного списка. Для простоты давайте используем командную строку и передаем условия в виде аргумента исполняемому файлу. Кроме того, поскольку он прост и короток, используйте сигнал.

Файл optional_functions.c

#include <stdio.h>
#include <stdlib.h>

#include <dlfcn.h>

static void a(void)
{
  puts("Function \"a\" called");
}

static void b(void)
{
  puts("Function \"b\" called");
}

static void c(void)
{
  puts("Function \"c\" called (by signal SIGINT)");
}

#include<signal.h>
#include<unistd.h>

static void signal_handler(int signal_number)
{
  if (signal_number == SIGINT) {
    c();
    exit(EXIT_SUCCESS);
  }
}


int main(int argc, char **argv)
{
  void *dynlib;
  void (*function_d) (void);
  char *dynlib_error;

  if (argc == 2) {
    if (argv[1][0] == 'a') {
      a();
    } else if (argv[1][0] == 'b') {
      b();
    } else if (argv[1][0] == 'd') {
      puts("External function \"d\" wanted, loading library");
      dynlib = dlopen("libfunctiond.so", RTLD_LAZY);
      if (dynlib == NULL) {
        fprintf(stderr, "Failed loading lib: %s\n", dlerror());
        exit(EXIT_FAILURE);
      }
      *(void **) (&function_d) = dlsym(dynlib, "d");
      dynlib_error = dlerror();
      if (dynlib_error != NULL) {
        fprintf(stderr, "Failed calling function \"d\" fom lib: %s\n",
                dynlib_error);
        exit(EXIT_FAILURE);
      }
      (*function_d) ();

    } else {
      fprintf(stderr, "A function named \"%c\" does not exist, bailing out\n",
              argv[1][0]);
      exit(EXIT_FAILURE);
    }
  } else {
    if (signal(SIGINT, signal_handler) == SIG_ERR) {
      fprintf(stderr, "signal catching failed, bailing out\n");
      exit(EXIT_FAILURE);
    }
    sleep(5);
    puts("Signal catching timed out, assuming no function wanted in the first place.");
  }
  exit(EXIT_SUCCESS);
}

Файл functiond.h

#ifndef FUNCTIOND_H
#define FUNCTIOND_H
void d(void);
#endif

Файл functiond.c

#include <stdio.h>
#include "functiond.h"
void d(void)
{
  puts("Function \"d\" called and says hello from the library");
}

Скомпилируйте как

clang -Weverything -fPIC  -c functiond.c
clang -shared -Wl,-soname,libfunctiond.so.1 -o libfunctiond.so.1.0   functiond.o
ln -sf libfunctiond.so.1.0 libfunctiond.so.1
ln -sf libfunctiond.so.1 libfunctiond.so
clang -Weverything -o optional_functions optional_functions.c example.c -ldl

Запустите его

$ ./optional_functions # waiting 5 seconds
Signal catching timed out, assuming no function wanted in the first place.
$ ./optional_functions # press CTRL+c in less than 5 seonds
^CFunction "c" called (by signal SIGINT)
$ ./optional_functions 1
A function named "1" does not exist, bailing out.
$ ./optional_functions a
Function "a" called
$ ./optional_functions b
Function "b" called
$ ./optional_functions d
External function "d" wanted, loading library
Failed loading lib: libfunctiond.so: cannot open shared object file: No such file or directory

Это ожидалось. Либо дайте dlopen() полный путь к библиотеке, либо позвольте переменной среды LD_LIBRARY_PATH выполнить работу:

$ LD_LIBRARY_PATH=. ./optional_functions d
External function "d" wanted, loading library
Function "d" called and says hello from the library

Это неправильный способ создания, установки и использования динамических c библиотек. конечно, но опять же: ради простоты ...

...