int add(int a, int b) // C funcion for addition
{
return(a+b);
}
we use extern to use printf , scanf etc. C library
how to call above add fuction defined in another *.c file or *.h file ?
Related
I wish to pass a lostanza function to a C API, where it will be called from C.
This is my current implementation :
; callbacks.stanza
defpackage callbacks :
import core
extern call_from_c : (ptr<(() -> int)>) -> int
lostanza defn my-callback () -> int :
return 42
lostanza defn call-from-c () -> ref<Int> :
val ret = call-c call_from_c(addr(my-callback))
return new Int{ret}
println(call-from-c())
With corresponding C file :
// call_from_c.c
int call_from_c (int (*callback)()) {
return callback();
}
I compile this code with stanza callbacks.stanza -ccfiles call_from_c.c -o cbk, but when running it I get this error message :
$ ./cbk
FATAL ERROR: Stack overflow
in core/fatal!
at core/core.stanza:374.2
in core/extend-stack
at core/core.stanza:2438.9
Segmentation fault (core dumped)
What do I need to be doing in order to set up the call to lostanza from C?
You're basically almost there. The one change you need is to change lostanza defn my-callback to extern defn my_callback.
There are two changes in there:
You extern defn to signal that this function is meant to be called using the C calling convention, instead of the standard Stanza convention.
The name got changed to my_callback. This is because the Stanza compiler will generate an assembly function that can be called from C for extern defn definitions. And since C does not allow hyphens in names, that means that you have to use an underscore instead.
I am trying to use Collections-C in Cython.
I noticed that some structures are defined in the .c file, and an alias for them is in the .h file. When I try to define those structures in a .pxd file and use them in a .pyx file, gcc throws an error: storage size of ‘[...]’ isn’t known.
I was able to reproduce my issue to a minimum setup that replicates the external library and my application:
testdef.c
/* Note: I can't change this */
struct bogus_s {
int x;
int y;
};
testdef.h
/* Note: I can't change this */
typedef struct bogus_s Bogus;
cytestdef.pxd
# This is my code
cdef extern from 'testdef.h':
struct bogus_s:
int x
int y
ctypedef bogus_s Bogus
cytestdef.pyx
# This is my code
def fn():
cdef Bogus n
n.x = 12
n.y = 23
print(n.x)
If I run cythonize, I get
In function ‘__pyx_pf_7sandbox_9cytestdef_fn’:
cytestdef.c:1106:9: error: storage size of ‘__pyx_v_n’ isn’t known
Bogus __pyx_v_n;
^~~~~~~~~
I also get the same error if I use ctypedef Bogus: [...] notation as indicated in the Cython manual.
What am I doing wrong?
Thanks.
Looking at the documentation for your Collections-C library these are opaque structures that you're supposed to use purely through pointers (don't need to know the size to have a pointer, while you do to allocate on the stack). Allocation of these structures is done in library functions.
To change your example to match this case:
// C file
int bogus_s_new(struct bogus_s** v) {
*v = malloc(sizeof(struct bogus_s));
return (v!=NULL);
}
void free_bogus_s(struct bogus_s* v) {
free(v);
}
Your H file would contain the declarations for those and your pxd file would contain wrappers for the declarations. Then in Cython:
def fn():
cdef Bogus* n
if not bogus_s_new(&n):
return
try:
# you CANNOT access x and y since the type is
# designed to be opaque. Instead you should use
# the acessor functions defined in the header
# n.x = 12
# n.y = 23
finally:
free_bogus_s(n)
I am trying to change the name of a running process under linux. In C, I would just modify argv[0] in-place, but how can I do that from haskell? I noticed that ghc has a primitive called getProgArgv:
foreign import ccall unsafe "getProgArgv"
getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()
but I tried with that and it didn't work. Also, I am aware of prctl(PR_SET_NAME,"...") but that only changes the current thread's name, and most tools (such as ps and htop) do not use that name.
Ok, so I came up with an ugly hack that seems to work. It based on a idea borrowed from here. We have to use an auxiliary c file:
#include <string.h>
#include <sys/prctl.h>
char *argv0 = 0;
static void capture_argv0(int argc, char *argv[]) {
argv0 = argv[0];
}
__attribute__((section(".init_array"))) void (*p_capture_argv0)(int, char*[]) = &capture_argv0;
void set_prog_name(char *name) {
if (!argv0) return;
size_t len = strlen(argv0);
strncpy(argv0, name, len);
prctl(PR_SET_NAME, name);
}
This relies on the section(".init_array") attribute that tells gcc to register capture_argv0 as an initialization function. This means that it will be executed before main. We use it to make a copy of the argv[0] pointer and store it as a global variable. Now we can call set_prog_name from haskell.
I came across a problem recently.
I have three files, A.h, B.cpp, C.cpp:
A.h
#ifndef __A_H__
#define __A_H__
int M()
{
return 1;
}
#endif // __A_H__
B.cpp
#include "A.h"
C.cpp
#include "A.h"
As I comile the three files by MSVC, there is a error:
C.obj : error LNK2005: "int __cdecl M(void)" (?M##YAHXZ) already defined in B.obj
It is easy understanding, as we know, B.obj has a symbol named "M", also C.obj has a "M".
Here the error comes.
However, if I change M method to a class which contain a method M like this below:
A.h
#ifndef __A_H__
#define __A_H__
class CA
{
public:
int M()
{
return 1;
}
};
#endif // __A_H__
there is no more errors!! Could somebody tell me what is happening?
If B.cpp and C.cpp include A.h, then both are compiled with your definition of M, so both object files will contain code for M. When the linker gathers all the functions, he sees that M is defined in two object files and does not know which one to use. Thus the linker raises an LNK2005.
If you put your function M into a class declaration, then the compiler marks/handles M as an inline function. This information is written into the object file. The linker sees that both object files contain a definition for an inline version of CA::M, so he assumes that both are equal and picks up randomly one of the two definitions.
If you had written
class CA {
public:
int M();
};
int CA::M()
{
return 1;
}
this would have caused the same problems (LNK2005) as your initial version, because then CA::M would not have been inline any more.
So as you might guess by now, there are two solutions for you. If you want M to be inlined, then change your code to
__inline int M()
{
return 1;
}
If you don't care about inlining, then please do it the standard way and put the function declaration into the header file:
extern int M();
And put the function definition into a cpp file (for A.h this would ideally be A.cpp):
int M()
{
return 1;
}
Please note that the extern is not really necessary in the header file.
Another user suggested that you write
static int M()
{
return 1;
}
I'd not recommend this. This would mean that the compiler puts M into both of your object files and marks M as being a function that is only visible in each object file itself. If the linker sees that a function in B.cpp calls M, it finds M in B.obj and in C.obj. Both have M marked as static, so the linker ignores M in C.obj and picks the M from B.obj. Vice versa if a function in C.cpp calls M, the linker picks the M from C.obj. You will end up with multiple definitions of M, all with the same implementation. This is a waste of space.
See http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html how to do ifdef guards. You have to start with ifndef before the define.
Edit: Ah no, while your guard is wrong that's not the issue. Put static in front of your function to make it work. Classes are different because they define types.
I don't know what's under the hood, but if you don't need a class I guess that the compiler will automatically add the "extern" key to your functions, so you'll get the error including the header 2 times.
You can add the static keyword to M() method so you'll have only one copy of that function in memory and no errors at compile time.
By the way: I see you have a #endif, but not a #ifdef or #ifndef, is it a copy/paste error?
I must do a horrible thing, i.e. automatically substitute a function call with a different function call, with different number of parameters, at precompilation time.
Example:
#include <iostream>
int FuncToChange(void* a, int b, void* c, int d) {
return 0;
}
int NewFunc(void* a, void* c, int d) {
return 1;
}
#define FuncToChange($1, $2, $3, $4) NewFunc($1, $3, $4)
int main()
{
int a = 1, b = 2, c = 256;
int v = FuncToChange(&a + 1, c + 1, &b, 2*c);
}
This code works, i.e. in main() NewFunc() is called instead of FuncToChange().
Now I would like to remove that #define (the reason is that I cannot modify the code), and obtain the same result setting the IDE's build options.
The IDE is CodeBlocks 10.05.
I already tried to add what follows to Project / Project Build Options / Compiler Settings / #define:
NewFunc($1, $3, $4)=FuncToChange($1, $2, $3, $4)
but nothing changed. Does anybody have any idea?
Thank you in advance!
Pietro
Platform:
GCC/MinGW
Windows7 64 bit
Reason behind this question:
I have to port an Excel plugin from XP 32 bit to Windows 7 64 bit. The plugin has been developed with CodeBlocks, and I cannot change tool set. The file FRAMEWRK.C (part of "2010 Office System Developer Resources", Excel2010 XLL SDK) has evolved, and now uses calls to non standard functions such as memcpy_s(), not available in MinGW. So, with the preprocessor, I substitute memcpy_s() with memcpy(), taking care of the different parameters.
Ok. I moved the #define in its own include file. Then I specified it to GCC, with the -include command line option.
Doing so, the file is included at the top of every source file.