I have a simple C function which I would like to pass an array of pointers to various strings. I am having trouble with the compiler barking at my function call parameters. Here is simple representation of what I am doing,
myfunction.h
int myServices(int, char *[]);
myfunction.c
#include <myfunction.h>
int myService(int value, char *strpointer[]) {
***
}
mainroutine.c
#include <myfuntion.h>
void main () {
// Initialize Parameters
int result;
int stringcnt;
char string1[8] = "-st";
char string2[8] = "-ir";
char * stringptr[10];
// Initialize stringptr
stringptr[0] = string1;
stringptr[1] = string2;
stringcnt = 2;
// Call Service
result = myService(stringcnt, stringptr); <== gcc issue with stringptr
}
The C compiler keeps giving me a "invalid use of member (did you forget the '&'?" with the stringptr in the myService call. I tried '&' and '*' with stringptr in the myService call in the main routine with no luck. Any ideas.
I ran your code and notices a few things: first of all in your header file you didn't define the arguments properly (case of the missing coma), and likewise your main entry point did not have the proper return type (needs to be int) nor arguments (int argc, char *argv[]). I've made the changes and attached them below:
// func.h
int myService(int, char*[]);
Then the function code:
// func.c
#include "func.h"
int myService(int value, char *strpointer[]) {
// your code here
return 0;
}
// prog.c
-
#include "func.h"
int main (int argc, char *argv[]) {
// Initialize Parameters
int result;
int stringcnt;
char string1[8] = "-st";
char string2[8] = "-ir";
char * stringptr[10];
// Initialize stringptr
stringptr[0] = string1;
stringptr[1] = string2;
stringcnt = 2;
// Call Service
result = myService(stringcnt, stringptr);
return 0;
}
I compiled this using the command gcc -o prog.o prog.c func.c with no errors and smooth execution. Hope this works for you
Related
Is it possible somehow to check at compile time or at run time that variable has static storage-class specifier?
Example:
static int v1;
int v2;
bool r1 = is_static(v1); /* true */
bool r2 = is_static(v2); /* false */
Disclaimer: The following code is not standards compliant, portable, or even safe. Please don't use it in production.
We can determine whether a variable is static by checking whether it is on the stack. Out function is_static() takes two arguments. The first is a pointer to our variable that we want to check and the second is a pointer to the beginning of the stack (that's what a is for). It then uses getrlimit() to determine the location of the end of that stack and checks whether our variable is on the stack. This should work on most unix-like systems.
#include <stdio.h>
#include <sys/resource.h>
_Bool is_static(void* var, char* stack_start)
{
struct rlimit stack; // Use getrlimit to get the maximum stack size.
getrlimit(RLIMIT_STACK, &stack); // TODO only run this once.
char* stack_end = stack_start - stack.rlim_cur; // Work out where the end of the stack is.
return !((char*)var < stack_start && (char*)var > stack_end) // Return whether the variable is on the heap.
}
int main()
{
char a = 0;
int b = 42;
static int c = 42;
printf("is_static(b) returns %i\n", is_static(&b, &a));
printf("is_static(c) returns %i\n", is_static(&c, &a));
}
We run the code and get this:
is_static(b) returns 0
is_static(c) returns 1
EDIT: If you don't want to use getrlimit(), then you could use __builtin_return_address() to determine the highest stack value.
Ok, turns out that my previous answer didn't work for static global variables, so I have devised this program that can check whether a global variable is declared static. The way it works is that dysym() can't find static globals in the symbol table, so I just check it's output. It also references the variable with a boolean and, to ensure it actually exists.
#include <stdio.h>
#include <dlfcn.h>
char* a = "hello, world";
static char* b = "hello, world";
#define is_static(name) \
(is_sym_static(#name) && &name)
_Bool is_sym_static(const char* const name)
{
void* hdl = dlopen(NULL, 0); // TODO: optimise by only calling this once.
return dlsym(hdl, name) == NULL;
}
int main(int argc, char** argv)
{
printf("%i\n", is_static(a)); // prints 0
printf("%i\n", is_static(b)); // prints 1
}
This must be compiled with -ldl -Wl,--export-dynamic, to ensure that all variables end up in the symbol table. This doesn't work for local variables, but we can combine it with my previous answer and...
#include <stdio.h>
#include <dlfcn.h>
#include <sys/resource.h>
static char* stack_start;
#define is_static(name) \
(is_addr_static(&name) && is_sym_static(#name) && &name)
_Bool is_sym_static(const char* const name)
{
void* hdl = dlopen(NULL, 0); // TODO: optimise by only calling this once.
return dlsym(hdl, name) == NULL;
}
_Bool is_addr_static(void* var)
{
struct rlimit stack;
getrlimit(RLIMIT_STACK, &stack); // TODO: optimise by only calling this once.
char* stack_end = stack_start - stack.rlim_cur;
return !((char*)var < stack_start && (char*)var > stack_end);
}
char* a = "hello, world";
static char* b = "hello, world";
int main(int argc, char** argv)
{
char _;
stack_start = &_;
char* c = "hello, world";
static char* d = "hello, world";
printf("%i\n", is_static(a)); // prints 0
printf("%i\n", is_static(b)); // prints 1
printf("%i\n", is_static(c)); // prints 0
printf("%i\n", is_static(d)); // prints 1
}
This now detects both global and local static variables. I see no reason to need this however, since local static and global static are fundamentally different things.
I want to retrieve global variable x I just set in Julia from my C application.
Here's the code I have so far:
#include <julia.h>
void SimpleExecute(char *command, char *resultVar, char* result) {
jl_eval_string(command);
jl_value_t *var = jl_get_global(jl_base_module, jl_symbol(resultVar));
const char *str = jl_string_ptr(var);
sprintf(result, "%s", str);
}
int main(int argc, char *argv[])
{
char* result = malloc(sizeof(char) * 1024);
jl_init();
//(void)jl_eval_string("println(sqrt(2.0))"); //works
(void)SimpleExecute("x=sqrt(2.0)", "x", result);
jl_atexit_hook(0);
return 0;
}
However debugger shows that var is still NULL after jl_get_global call. Why?
I followed this tutorial but it does not touch on arbitrary variable retrieval. Source code shows similar usage.
I think there are a few things going on here:
First, you need to use jl_main_module and not jl_base_module.
Second, you cannot use jl_string_ptr to get the string value of a integer or floating point value. You can either use x=string(sqrt(2.0)) as the command to run, or use jl_unbox_float64 as a function to unbox the value you get back from Julia.
#include <julia.h>
#include <stdio.h>
void SimpleExecute(char *command, char *resultVar, const char* result) {
jl_eval_string(command);
jl_value_t *var = jl_get_global(jl_main_module, jl_symbol(resultVar));
if (var && jl_is_string(var)) {
const char * str = jl_string_ptr(var);
printf("%s\n", str);
} else {
const double val = jl_unbox_float64(var);
printf("%f\n", val);
}
}
int main(int argc, char *argv[])
{
char* result = malloc(sizeof(char) * 1024);
jl_init();
// (void)jl_eval_string("println(sqrt(2.0))"); //works
(void)SimpleExecute("x = sqrt(2.0)", "x", result);
jl_atexit_hook(0);
return 0;
}
You can run this by modifying the following:
cc -I/Users/$USER/Applications/Julia-1.3.app/Contents/Resources/julia/include/julia/ -Wl,-rpath,/Users/$USER/Applications/Julia-1.3.app/Contents/Resources/julia/lib/ -L/Users/$USER/Applications/Julia-1.3.app/Contents/Resources/julia/lib/ -ljulia main.c -o main
I am having a problem with passing a pointer to a function. When the function returns the pointer seems to be different than what it is in the function.
So I pass a pointer to the function which gets raw image data which should then be stored in the memory referenced by the pointer.
If I then pass the pointer from inside the raw image function to a function to create a JPEG file from the raw data then it works correctly.
If I first wait for the raw image function to finish and then call the JPEG function using the pointer I passed to the raw image function then it fails to create the image.
A simplified version of the code is below:
int getRawImage(unsigned char *pBuffer);
int writeJPEGBFile(unsigned char *idata, char *ofile);
int main(int argc, char** argv) {
unsigned char *rawData = NULL;
char filename[MAXPATHLEN] = "/home/user/tst/img.jpg";
getRawImage(rawData);
// This does not work
writeJPEGBFile(rawData, filename);
free(rawData);
return 0;
}
int getRawImage(unsigned char *pBuffer) {
void *hDevice;
hDevice = scanOpenDevice();
// Removed code for simplification
scanGetFrame(hDevice, pBuffer, NULL)
scanCloseDevice(hDevice);
// This Works!!
//char filename[MAXPATHLEN] = "/home/user/tst/img.jpg";
//writeJPEGBFile(pBuffer, filename);
return 0;
}
int writeJPEGBFile(unsigned char *idata, char *ofile) {
// JPEG code goes here
return 0;
}
My question is what am I doing wrong and how can I pass the rawData pointer to the writeJPEGBFile() function successfully in the main() function?
The definition for scanGetFrame() is as follows:
typedef void *FTR_PVOID;
FTR_API_PREFIX FTR_BOOL FTR_API ftrScanGetFrame( FTRHANDLE ftrHandle, FTR_PVOID pBuffer, PFTRSCAN_FRAME_PARAMETERS pFrameParameters );
The scanGetFrame() function comes from a 3rd party library that I am linking with so I will not be able to change the definition.
Given that rawData is a null pointer in main(), you almost certainly need to revise the interface to getRawImage() so that it takes a char ** and you pass &rawData to it. You also need to think about how the calling code will know how big the data is.
I managed to work it out. Thanks to all for the pointers which led me to the solution:
int getRawImage(unsigned char *pBuffer);
int writeJPEGBFile(unsigned char *idata, char *ofile);
int main(int argc, char** argv) {
unsigned char *rawData; // Removed the NULL assignment
char filename[MAXPATHLEN] = "/home/user/tst/img.jpg";
// Set the size of rawData - loadImageSize() sets the value of the ImageSize class variable.
loadImageSize();
rawData = (unsigned char *) malloc(ImageSize.nImageSize);
getRawImage(rawData);
// This works now
writeJPEGBFile(rawData, filename);
free(rawData);
return 0;
}
int getRawImage(unsigned char *pBuffer) {
void *hDevice;
hDevice = scanOpenDevice();
// Removed code for simplification
scanGetFrame(hDevice, pBuffer, NULL)
scanCloseDevice(hDevice);
return 0;
}
int writeJPEGBFile(unsigned char *idata, char *ofile) {
// JPEG code goes here
return 0;
}
After some research I didn't find a good way to implement the std::bind in C.
I build a small program that implements an equivalent of std::bind in C by hacking the stack.
There's two functions I will try to bind to function with pre-defined arguments.
My problem is this code is only working under Windows. Under Linux, this is a mess. I this the problem is my knowledge of the stack and the way that arguments are store in memory.
Thanks,
Please, find below the code I made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
The two functions I want to bind :
void test1 (int nombre, char t, int nombre2)
{
printf ("test 1 : %d%c%d\n", nombre, t, nombre2);
}
void test2 (char t, int nombre, int nombre2)
{
printf ("test 2 : %c%d%d\n", t, nombre, nombre2);
}
Two struct that will store the argument of each function (order of fields is important).
typedef struct {
int nombre;
char t;
int nombre2;
} struct1;
typedef struct {
char t;
int nombre;
int nombre2;
} struct2;
This "fake" struct will be use to write on the stack by dereferencing a structvoid* variable.
// Size must be bigger than every struct*
typedef struct {
int i[10];
} structvoid;
The main function.
int main(int argc, char** argv) {
// Variables to store the two functions and their arguments.
void * functions[2];
structvoid * data[2];
void *func1 = (void *)&test1;
void *func2 = (void *)&test2;
void (*functionPtrc)(structurevoid);
// Definition of the argument of the first function test1
struct1 data1;
data1.nombre = 15;
data1.t = 'c';
data1.nombre2 = 30;
// and storing data.
void *datac = malloc (sizeof (structvoid));
memcpy(datac, &data1, sizeof (struct1));
data[0] = (structvoid*)datac;
functions[0] = func1;
// Same thing with function 2.
struct2 data2;
data2.t = 'a';
data2.nombre = 5;
data2.nombre2 = 10;
datac = malloc (sizeof (structvoid));
memcpy(datac, &data2, sizeof (struct2));
data[1] = (structvoid*)datac;
functions[1] = func2;
// Get the pointer to the first function (test1);
functionPtrc = functions[0];
// All the hack is here. By dereferencing the data, this will write on the stack all arguments need by the test1 function.
functionPtrc(*data[0]);
functionPtrc = functions[1];
functionPtrc(*data[1]);
// To check the result.
test1 (data1.nombre, data1.t, data1.nombre2);
test2 (data2.t, data2.nombre, data2.nombre2);
return 0;
}
EDIT
Here a new version of the program by calling function via the calling convention. I only wrote the new lines. The problem of this method is I can only store data inside a "void *" field. If I increase the size of structvoid, I got garbage behaviors.
// Structure that memories each argument
typedef struct {
void *i[1];
} structvoid;
int main(int argc, char** argv) {
// Variables to store the two functions and their arguments.
void * functions[2];
structvoid * data[2];
void *func1 = (void *)&test1;
// Let's start with a maximum of 5 arguments
void (*functionPtrc)(structurevoid, structurevoid, structurevoid, structurevoid, structurevoid);
// Definition of the argument of the first function test1
struct1 data1;
data1.nombre = 15;
data1.t = 'c';
data1.nombre2 = 30;
// and storing data.
structvoid *datac = malloc (sizeof (structvoid)*5);
memcpy(&datac[0], &data1.nombre, sizeof (data1.nombre));
memcpy(&datac[1], &data1.t, sizeof (data1.t));
memcpy(&datac[2], &data1.nombre2, sizeof (data1.nombre2));
data[0] = datac;
functions[0] = func1;
// Get the pointer to the first function (test1);
functionPtrc = functions[0];
// Call the function with the arguments. The unused argument will be ignored.
functionPtrc(data[0][0], data[0][1], data[0][2], data[0][3], data[0][4]);
}
This procedure should convert a string that contains a set of double numbers separated by comma (e.g. 7.2,9.5,-5.515) to a vector of double type.
void ToDoubleVec(int d,const char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
Here is the snippet of program that calls it:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc,char** argv)
{
...
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
...
}
Debugger's output:
40 lower = malloc(dim*sizeof(double));
(gdb) s
42 ToDoubleVec(dim,argv[2],lower);
(gdb) s
ToDoubleVec (d=2, commaSeparated=0x7fffffffe9d3 "2.3,-62.1", result=0x603010) at testPSO.c:11
11 result[0]=atof(strtok(commaSeparated,","));
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff77f56bb in ?? () from /lib/x86_64-linux-gnu/libc.so.6
Why doesn't it work? I was sure that I've allocated enough memory for the array and also parameters seems to be passed correctly.
You can reduce your code to this SSCCE (Short, Self-Contained, Correct Example), which crashes nicely when you leave out #include <string.h> and does not compile cleanly when you add #include <string.h>:
segv.c: In function ‘ToDoubleVec’:
segv.c:8:5: warning: implicit declaration of function ‘strtok’ [-Wimplicit-function-declaration]
segv.c:8:20: warning: initialization makes pointer from integer without a cast [enabled by default]
segv.c:14:20: warning: assignment makes pointer from integer without a cast [enabled by default]
Code:
#include <stdlib.h>
//#include <string.h>
static void ToDoubleVec(int d, const char* commaSeparated, double *result)
{
int i;
result[0] = atof(strtok(commaSeparated, ","));
for (i = 1; i < d; i++)
result[i] = atof(strtok(NULL, ","));
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
ToDoubleVec(dim, arg, lower);
}
Passing the return value from a function such as strtok() which can return a null pointer directly to a function such as atof() which does not tolerate null pointers is foolhardy; it leads to crashes. If everything is correct, you'll be OK; if not, you'll crash and burn.
The unchecked memory allocation is a similar problem; you didn't even check that dim was non-zero (and non-negative) before doing the memory allocation in the original.
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static void ToDoubleVec(int d, char *commaSeparated, double *result)
{
int i;
char *number = strtok(commaSeparated, ",");
if (number != 0)
{
result[0] = atof(number);
for (i = 1; i < d; i++)
{
number = strtok(NULL, ",");
if (number != 0)
result[i] = atof(number);
}
}
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
assert(lower != 0);
ToDoubleVec(dim, arg, lower);
}
You could — and in one version of the code I did — add error printing to report if the tests on number failed. But the crash is caused by the implicit declaration of strtok() as returning int and not char *.
I have tried to compile your code, and the compiler warned me that strtok() takes as input a char* and not a const char*. Then I have tried this code, and it is working correctly:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void ToDoubleVec(int d, char* commaSeparated,double *result);
int main(int argc,char** argv)
{
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
for (i=0; i<dim; ++i) {
printf("%f\n", lower[i]);
}
return 0;
}
void ToDoubleVec(int d, char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
So try to change const char* to char*, and check the input you pass to your program, maybe it is not correct and this could be the problem.