Is it possible? i.e. compile .c with dmc and .d with dmd and then link them together, will this work? Will I be able to call D functions from C code, share globals etc? Thanks.
Yes it is possible. In fact this is one of the main feature of dmd. To call a D function from C, just make that function extern(C), e.g.
// .d
import std.c.stdio;
extern (C) {
shared int x; // Globals without 'shared' are thread-local in D2.
// You don't need shared in D1.
void increaseX() {
++ x;
printf("Called in D code\n"); // for some reason, writeln crashes on Mac OS X.
}
}
// .c
#include <stdio.h>
extern int x;
void increaseX(void);
int main (void) {
printf("x = %d (should be 0)\n", x);
increaseX();
printf("x = %d (should be 1)\n", x);
return 0;
}
See Interfacing to C for more info.
The above answer is wrong as far as I know.
Because the D main routine has to be called before you use any D functions.
This is necessary to "initialize" D, f.e. its garbage collection.
To solve that, you simply can make the program be entered by a main routine in D or you can somehow call the D main routine from C. (But I dont know exactly how this one works)
Related
I have written a program and i want to link it to another c program. In the sense, by using the include or any other directive, I need to link the programs, such that a function of the former can be called by the latter. How can i accomplish this in codebloacks ?
Suppose you have now two programs A and B. And in A you have function c. So, move c to separate file c.c and make c.h file, that can be included in both A and B program as #include "c.h". Than compile A and B independently.
It will be the simplest way.
EDIT:
All function that uses one another should be in the "library". E.g.:
// c.h
int c(int x1, int x2); // this will be called from outside
extern int callCount; // to be available outside
and
// c.c
#include "c.h"
int d(int x); // this cannot be called from outside
// global variable to count calls of c function
int callCount = 0;
int c(int x1, int x2)
{
callCount++; // changing of global variable
return (x1 + x2) * d(x1);
}
int d(int x)
{
return x * x;
}
and usage
// prog A
#include <stdio.h>
#include "c.h"
int main(void)
{
int a = 1, b = 2;
printf("c = %d\n", c(a, b));
printf("c = %d\n", c(2*a, b - 1));
printf("Function c was called %d times\n", callCount);
return 0;
}
All the functions that you are planning to call from other files should be declared in h-file. It is the common approach, but also lots of tips can be find in the Internet, such as static functions, #define detectives and conditional compilation, etc.
It (loading a C program in another one) cannot be stricto sensu done, since there is only one single main function in any given program. However the system(3) & popen(3) functions enable you to start another program -thru a command line- from a first one. On Linux and POSIX systems you also can start a process using fork(2) and you can execute a program in a process using execve(2). Of course this is operating system specific!
However, on some operating systems and platforms, you can use dynamic linking to load some plugin at runtime. The loaded plugin is not a program (it does not have any main function), but a library.
For example, on Linux and POSIX systems, you could use the dlopen function to load a plugin (often some shared library), and the dlsym function to get a symbol inside it.
On Linux, dlopen is loading an ELF shared object which should contain position-independent code.
PS. You can also link a library (at build time) to your program.
My a.c file:
int sum(int a, int b) {
return a + b;
}
My b.c file:
#include<stdio.h>
extern int sum(int, int);
int main() {
printf ("%d", sum(2, 3));
return 0;
}
gcc a.c b.c -o output, working fine.
Let say tomorrow, I change the definition of "a.c file" sum function by increasing the argument to three. Like this,
int sum(int a, int b, int c) {
return a + b + c;
}
But forget to change the usage in b.c file (means I'm still using with two variable)
gcc a.c b.c -o output (doesn't give compilation error or warning mssg, printf gives wrong answer, obviously)
Now consider I'm working in huge set of c file and I cannot make new header file, because it will create unnecessary dependency problem which may take huge time to resolve.
What is the best way to throw error or even warning message in case the extern original definition is changed in terms of argument ?
Regards
What is the best way to throw error or even warning message in case the extern original definition is changed in terms of argument?
Neither compiler nor linker will object to that. You'll just find out at runtime (if you are lucky) when your program stops working.
If this was C++ then name mangling would allow the linker to reject such mal-formed programs. However, for C the linker only needs to find a symbol with the right name. It has no means of checking the signature.
Using header files is the accepted way to get the compiler to make sure you do things right. Repeating function declarations over and over throughout your program is usually a very bad idea. Whatever downsides you perceive to using header files pale into insignificance when compared to your proposed approach.
If you simply won't use header files, then you'll just have to always be right!
Normally editors like (SourceInsight,Sublime) have the options to browse the symbols. By using this option you can easily find function calls and prototype.
Compiler never generate warnings or error for your problem.Self contained header files are best option to avoid this situation.
The best thing to do is try to avoid "extern" and include the header file for sum(). Using header files and prototyping your functions will help the compiler catch these issues.
test.c:
#include <stdio.h>
#include "math.h"
int main(void)
{
printf("%d", sum(2, 3));
return 0;
}
math.h:
int sum(int a, int b, int c)
{
return (a + b + c);
}
output:
~]$ gcc test.c -o test
test.c: In function ‘main’:
test.c:6:5: error: too few arguments to function ‘sum’
printf("%d", sum(2, 3));
^
In file included from test.c:2:0:
math.h:1:5: note: declared here
int sum(int a, int b, int c)
I have these files
test1.h
extern int value;
void inc_value();
int print_value();
test1.c
#include "test1.h"
int value=0;
void inc_value()
{
printf("inc value from test3.c = %d\n", value++);
}
int print_value()
{
printf(" value in test1.c = %d\n", value);
return value;
}
test3.c
# include "test1.h"
main()
{
inc_value();
}
test4.c
# include <stdio.h>
#include "test1.h"
main()
{
printf("value from test4 = %d\n", print_value());
}
I'm updating variable "value" from test3.c and trying to read it from test4.c. However test3.c is unable to update the "value" that is declared in test1.h and defined in test1.c
What point am I missing here..
This will never work.
You can't use an external variable from two different programs and magically expect it to work. It's just ... wrong. Each program runs in its own address space, and doesn't know anything about any other process' address spaces. There are techniques for doing this (look up interprocess communucation), but that's a whole different area.
The way extern works is that it allows you to access a variable defined in a different C file within the same program.
You seem to be mis-understanding at a quite fundamental level how the programs you are writing work and execute, since you expect this to work. I recommend reading up more on how C works, and also perhaps a bit on how operating systems host programs in order to run them.
One way of sharing information between programs like you describe is to store the data in a file, which is written by one program (the one that runs first) and read by the other, but that is quite tricky to get right, too.
If you want to call void inc_value() from another file, you should declare it (probably in the header):
void inc_value();
If you want to directly access value, you can, as it was declared as an extern:
# include "test1.h"
main()
{
value = 6;
}
Also note, that in current implementation of inc_value, the value will be incremented after it is passed to printf, e.g. the printed value will be the previous one.
You should put extern int value in the test3.c and just put int value in test1.h.Look at this link: http://www.learncpp.com/cpp-tutorial/42-global-variables/ Hope this helps...
What I would like is a tool to be able to tell me which functions call a particular function A() (in a C project), and which functions call those functions etc so that I can have a list of functions which i know that when they are called, there is a possibility that function A() will be called.
For example we have the following functions scattered in a project:
void A()
{ /*does something*/ }
void B()
{
A();
/*and more stuff*/
}
void C()
{
if(unlikely_to_be_false)
A()
/* moar stoff */
}
void D()
{
/* code that does not refer to A() at all */
}
void E()
{
C()
}
When the awesome tool is run with parameter A, It will return somehow a the functions B C and E.
Close to this but not exactly i would like to accomplish this:
Given a variable somewhere in a project find all read/write operations(direct or indirect) to it.
For example:
void A()
{
char* c; // this is our little variable
B(c); // this is in the resulting list
}
void B(char* x)
{
printf("%c", x); // this is definately in the list
*x='d' // this is also in the list
C(x); // also in the list
}
void C(void* ptr)
{
ptr = something; // also in the list
}
If the above could play well with emacs i would be most delighted!
You could have a look on cscope tool (http://cscope.sourceforge.net/). It supports very large projects and a lot of different queries type :
Find this C symbol
Find this global definition
Find functions called by this function
Find functions calling this function
...
First, there is the issue of calls between different compilation units, e.g. foo.c defining function foo1 calling function bar2 defined in bar.c (and that bar2 might call a foobar defined in foo.c or in another file foofoo.c)
Then, you might consider perhaps developing a GCC plugin or a MELT extension to suit your needs.
You could also buy a costly static analyzer tool.
Emacs has cedet which might interest you.
I have a dynamic library that contains a constructor.
__attribute__ ((constructor))
void construct() {
// This is initialization code
}
The library is compiled with -nostdlib option and I cannot change that. As a result there are no .ctor and .dtor sections in library and the constructor is not running on the library load.
As written there there should be special measures that allow running the constructor even in this case. Could you please advice me what and how that can be done?
Why do you need constructors? Most programmers I work with, myself included, refuse to use libraries with global constructors because all too often they introduce bugs by messing up the program's initial state when main is entered. One concrete example I can think of is OpenAL, which broke programs when it was merely linked, even if it was never called. I was not the one on the project who dealt with this bug, but if I'm not mistaken it had something to do with mucking with ALSA and breaking the main program's use of ALSA later.
If your library has nontrivial global state, instead see if you can simply use global structs and initializers. You might need to add flags with some pointers to indicate whether they point to allocated memory or static memory, though. Another method is to defer initialization to the first call, but this can have thread-safety issues unless you use pthread_once or similar.
Hmm missed the part that there where no .ctor and .dtor sections... forget about this.
#include <stdio.h>
#include <stdint.h>
typedef void (*func)(void);
__attribute__((constructor))
void func1(void) {
printf("func1\n");
}
__attribute__((constructor))
void func2(void) {
printf("func2\n");
}
extern func* __init_array_start;
int main(int argc, char **argv)
{
func *funcarr = (func*)&__init_array_start;
func f;
int idx;
printf("start %p\n", *funcarr);
// iterate over the array
for (idx = 0; ; ++idx) {
f = funcarr[idx];
// skip the end of array marker (0xFFFFFFFF) on 64 bit it's twice as long ;)
if (f == (void*)~0)
continue;
// till f is NULL which indicates the start of the array
if (f == NULL)
break;
printf("constructor %p\n", *f);
f();
}
return 0;
}
Which gives:
Compilation started at Fri Mar 9 09:28:29
make test && ./test
cc test.c -o test
func2
func1
start 0xffffffff
constructor 0x80483f4
func1
constructor 0x8048408
func2
Probably you need to swap the continue and break if you are running on an Big Endian system but i'm not entirely sure.
But just like R.. stated using static constructors in libraries is not so nice to the developers using your library :p
On some platforms, .init_array/.fini_array sections are generated to include all global constructors/destructors. You may use that.