How to pass parameters in c from library linux - c

How to pass parameters from library in c programming language in linux?
I've tried this:
library.c code:
char test;
void GetParam()
{
test = "Creating test string here.";
}
header.h code
extern char test;
void GetParam(void);
program.c code
int main()
{
GetParam();
printf("%s\n", test);
}
but test returns empty.

char test just stores one character. If you want it to store a string, use char *test
PS: I'm a beginner; please correct me if I am wrong.

Related

Why is Cod::Blocks giving me Null instead of a input char?

Source Code:
#3 main.c
# include "func.h"
int main(void) {
func();
return 0;
}
#3 func.h
#include <stdio.h>
void inputName();
void printName();
void func();
#3 func.c
#include "func.h"
char GLOBAL_NAME;
void inputName() {
scanf("%s", &GLOBAL_NAME);
}
void printName() {
printf("Your name is: %s.\n", &GLOBAL_NAME);
}
void func(void) {
inputName();
printName();
}
Out Put:
Your name is: (null).
I used https://www.online-cpp.com/online_c_compiler with the same code, it works fine on the online compiler. but when I try to use it on Code::Blocks it shows me:
Your name is: (null).
Don't know what's the problem, Could it be a compiler thing?
I'm using a windows machine for Code::Blocks using GCC I think as the compiler.
Initialize your char variable with a length and since you have not initialized it with a length it returns NULL.
char GLOBAL_NAME[30];

How to use macro for calling function?

I want to call function according to func_name string.
My code is here below:
#define MAKE_FUNCNAME func_name##hello
void call_func(void* (*func)(void))
{
func();
}
void *print_hello(void)
{
printf("print_hello called\n");
}
int main(void)
{
char func_name[30] = "print_";
call_func(MAKE_FUNCNAME);
return 0;
}
But this code doesn't work. I want code to work like call_func(print_hello). But preprocessor treated my code like call_func("print_hello"). How to use macro in C to make my exception? Or is it not possible using C?
Then problem with your code is that the value of func_name is only known at run-time.
You can however to it like this:
#define MAKE_FUNCNAME(FUNCNAME) FUNCNAME##hello
void call_func(void* (*func)(void))
{
func();
}
void *print_hello(void)
{
printf("print_hello called\n");
}
int main(void)
{
call_func(MAKE_FUNCNAME(print_));
return 0;
}
But it is not possible to use a string value within macro parameters like in your code snippet.
If you want to get call functions with their names using string values you can use a table to store function pointer with function names like this:
struct {
const char *name;
void (*ptr)(void);
};
You can use an array of this structure to find out the function pointer at run-time using a string value. This is the most common solution to using run-time strings to call functions using their names.
You can't do that. The value of func_name is known at run-time (even though it is a const char *), while you want to determine what to call at precompile-time. You should turn your cpp macro into something different (such as an if/switch statement or using an indirection).
Maybe you could have a look to dlsym().
Not sure I really understand the question, but if you want to "build" the function name at runtime and then call the corresponding function, it should be possible with dlsym()
/* compile with: gcc example.c -ldl -rdynamic */
#include <dlfcn.h>
#include <stdio.h>
int print_hello(void)
{
return printf("hello\n");
}
int main(int argc, char *argv[])
{
const char *name = "print_hello";
if (argc == 42)
print_hello(); /* for compiler not to remove print_hello at
* compile time optimisation in this example*/
void *handle = dlopen(NULL /* self */, RTLD_NOW);
int (*f)(void) = dlsym(handle, name);
f();
return dlclose(handle);
}

Read string next to another in c

I have this code:
#include <stdio.h>
#include <strings.h>
int main(int ac, char **av)
{
char text[] = "PASS_KEY";
printf("Hey\n");
return 0;
}
I know those strings are literally next one to one in memory.
How can I redefine printf with LD_Preload to read text?
Defining a shim printf to dump memory around the pointer it is passed is not a difficult task:
#include <stdio.h>
void dump(const char *data) {
fwrite(data - 32, 1, 64, stdout);
}
int printf(const char *data, ...) {
dump(data);
}
Compile with:
gcc -c -fPIC print.c -o print.o
ld -shared -o libprint.so print.o
and now you can LD_PRELOAD=./libprint.so ./program and get the key. Or you could... You have a few separate problems here.
GCC at least optimizes a printf with no placeholders in the format string to a puts. So what gets called by your program is not printf. Well, let's shim puts too:
int puts(const char *data) {
dump(data);
}
now you get the dump on screen:
..............Hey........
so it's working. But there's no trace of the key. Why?
Because text is a local variable (array) and "Hey\n" is a constant string. So text is allocated on the stack and "Hey\n" in the constant pool, which is not exactly "next to it". Your assumption is wrong. If you modify the program as:
#include <stdio.h>
#include <strings.h>
int main(int ac, char **av)
{
char text[] = "PASS_KEY";
char format[] = "Hey\n";
printf(format);
return 0;
}
which, incidentally, is a thing you WOULD THINK TWICE BEFORE DOING because using non-constant format strings for printf is B.A.D. in most cases, it will work:
............Hey
PASS_KEY.
Success!

List environment variables with C in UNIX

Is there a way to enumerate environment variables and retrieve values using C?
Take a look at the environ global variable.
extern char **environ;
It might be defined in unistd.h (take a look at the environ (5) man page above).
Here's a little code demo I wrote:
#include <stdio.h>
extern char **environ;
int main()
{
for (char **env = environ; *env; ++env)
printf("%s\n", *env);
}
Here's how to use it:
matt#stanley:~/Desktop$ make enumenv CFLAGS=-std=c99
cc -std=c99 enumenv.c -o enumenv
matt#stanley:~/Desktop$ ./enumenv
ORBIT_SOCKETDIR=/tmp/orbit-matt
SSH_AGENT_PID=1474
TERM=xterm
SHELL=/bin/bash
... (so forth)
The environment information can be passed as an extra parameter to main. I don't know if it is compliant or not, but it definitely works (tested on Ubuntu). Just define the extra argument and its an array of char pointers terminated by a NULL pointer. The following will print out the lot.
#include <stdio>
int main(int argc, char *argv[], char *envp[])
{
int index = 0;
while (envp[index])
printf("%s\n", envp[index++];
}
There is a demo in the book "The Linux Programming Interface" at page 127.
Listing 6-3: Displaying the process environment
––––––––––––––––––––––––––––––––––––––––––––––––proc/display_env.c
#include "tlpi_hdr.h"
extern char **environ;
int
main(int argc, char *argv[])
{
char **ep;
for (ep = environ; *ep != NULL; ep++)
puts(*ep);
exit(EXIT_SUCCESS);
}

using #defines and passing functions to them

gcc 4.4.2 c89
I re-engineering some code in c89. However, I am totally confused with the code that uses the following #defines. So I created a small application that maybe I would understand more of how this is working.
From what I can gather the MODULE_API will pass a function name and call the macro MODULE_SOURCE_API and concatenate name and func. So I create a simple function called print_name and ran the code. I got the following error messages:
implicit declaration of function ‘print_name’
undefined reference to `print_name'
What would be the main reason for doing this?
#include <stdio.h>
#define MODULE_SOURCE_API(name, func) name##_##func
#define MODULE_API(func) MODULE_SOURCE_API(mod_print, func)
void MODULE_API(print_name)(const char const *name);
int main(void)
{
printf("=== Start program ===\n");
print_name("Joe bloggs");
printf("== End of program ===\n");
return 0;
}
void MODULE_API(print_name)(const char const *name)
{
printf("My name is [ %s ]\n", name);
}
Many thanks for any advice,
EDIT ====
I have just made a correction I should be calling
MODULE_API(print_name)("Joe Bloggs");
But how can I print out what will be the outcome of concatenating? And what is the reason for doing this?
Many thanks,
#define MODULE_SOURCE_API(name, func) name##_##func
#define MODULE_API(func) MODULE_SOURCE_API(mod_print, func)
void MODULE_API(print_name)(const char const *name);
That will be producing a function named mod_print_print_name instead of print_name
You can check it on gcc with the -E option.
gcc -E ak.c gives
/* ...... */
void mod_print_print_name(const char const *name);
int main(void)
{
printf("=== Start program ===\n");
print_name("Joe bloggs");
printf("== End of program ===\n");
return 0;
}
void mod_print_print_name(const char const *name)
{
printf("My name is [ %s ]\n", name);
}
You can try to manually expand the macros to understand what is going on:
void MODULE_API( print_name )( const char * name ); // the second const there is redundant
// maybe you meant 'const char * const??
=(expand MODULE_API)=>
void MODULE_SOURCE_API( mod_print, print_name )( const char* name );
=(expand MODULE_SOURCE_API)=>
void mod_print_print_name( const char *);
As you see, the function being declared (and defined at the end of the code) is not print_name, but rather mod_print_print_name. Go back to the initial code and see how the macro is intended to be used. I would assume that function calls are performed with the same macros that are used for declarations and definitions.

Resources