www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can't get them

reply "Bob W" <nospam aol.com> writes:
How do I access initialized global/static C variables from D?

D can call C functions, but if it tries to get e.g. an integer
value from a C object file directly it will read 0 whatever
the initialized value might be.

This works between two C object files, however. Why not
between a D and a C object file?
Apr 14 2005
next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <d3m7fb$1be8$1 digitaldaemon.com>, Bob W says...
How do I access initialized global/static C variables from D?

D can call C functions, but if it tries to get e.g. an integer
value from a C object file directly it will read 0 whatever
the initialized value might be.

This works between two C object files, however. Why not
between a D and a C object file?

It should work. Are the variable declarations labeled "extern (C)?" You might want to take a look at my standard C headers here: http://home.f4.ca/sean/d errno is exposed in errno.d and that's all I had to do to get it working. Sean
Apr 14 2005
next sibling parent "Bob W" <nospam aol.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message 
news:d3ma23$1eeh$1 digitaldaemon.com...

 It should work.

I thought so too.
  Are the variable declarations labeled "extern (C)?"

Yes, they are.
 You might want to take a look at my standard C headers here:

 http://home.f4.ca/sean/d

 errno is exposed in errno.d and that's all I had to do to get it working.

Looks simple enough, but for some reason this principle does not work here (dmd version 120.2). Maybe you can comment on the simplest of several attempts: Compiled the C source with dmc (-c option) to .obj static int b=1234; Wrote a D test program: import std.stdio; extern (C) int b; void main() { writefln("Value of b: %d",b); } Compiled and linked this with the C .obj file. When the program is run the output is 0 instead of the expected 1234. Why?
Apr 14 2005
prev sibling parent "Bob W" <nospam aol.com> writes:
Problem solved.

The 'static int' declaration was the troublemaker.

Thanks anyway.
Apr 14 2005
prev sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Bob W" <nospam aol.com> wrote in message 
news:d3m7fb$1be8$1 digitaldaemon.com...
 How do I access initialized global/static C variables from D?

 D can call C functions, but if it tries to get e.g. an integer
 value from a C object file directly it will read 0 whatever
 the initialized value might be.

 This works between two C object files, however. Why not
 between a D and a C object file?

Be sure you don't link in the object file containing the D declaration of the variable. See http://www.digitalmars.com/d/htomodule.html the section about "Extern Global C Variables". hope that helps, -Ben
Apr 14 2005
parent reply "Bob W" <nospam aol.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message 
news:d3maoq$1f4m$1 digitaldaemon.com...

 Be sure you don't link in the object file containing the D declaration of 
 the variable. See http://www.digitalmars.com/d/htomodule.html the section 
 about "Extern Global C Variables".

 hope that helps,

Sorry, it didn't. If the D declaration is not linked, the linker complains (Error 42: Symbol Undefined _GlobalCVariable). It might work w/o the underscore. If it IS linked, everything looks ok, just the program never gets the value of the C variable (e.g. always 0 for ints).
Apr 14 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
In article <d3mpie$1tdb$1 digitaldaemon.com>, Bob W says...
"Ben Hinkle" <bhinkle mathworks.com> wrote in message 
news:d3maoq$1f4m$1 digitaldaemon.com...

 Be sure you don't link in the object file containing the D declaration of 
 the variable. See http://www.digitalmars.com/d/htomodule.html the section 
 about "Extern Global C Variables".

 hope that helps,

Sorry, it didn't. If the D declaration is not linked, the linker complains (Error 42: Symbol Undefined _GlobalCVariable). It might work w/o the underscore. If it IS linked, everything looks ok, just the program never gets the value of the C variable (e.g. always 0 for ints).

The extern(C) int b needs to be in another file (like the example in the html doc). Judging from the other reply on this thread here's what I would do: file1.c int b = 1234; file2.d extern(C) int b; file3.d import std.stdio; import file2; void main() { writefln("Value of b: %d",b); } Compile file1.c and then run dmd file3.d file1.obj and be sure not to link in the file containing extern(C)b. If that doesn't work please post a more detailed transcript of your code and compiler input and output. hope that helps, -Ben ps - this thread should probably belong on digitalmars.D.learn.
Apr 14 2005
parent reply "Bob W" <nospam aol.com> writes:
"Ben Hinkle" <Ben_member pathlink.com> wrote in message 
news:d3mrpu$1v87$1 digitaldaemon.com...


 The extern(C) int b needs to be in another file (like the example in the 
 html
 doc). Judging from the other reply on this thread here's what I would do:
 file1.c
 int b = 1234;
 file2.d
 extern(C) int b;
 file3.d
 import std.stdio;
 import file2;
 void main() {
 writefln("Value of b: %d",b);
 }
 Compile file1.c and then run
 dmd file3.d file1.obj
 and be sure not to link in the file containing extern(C)b. If that doesn't 
 work
 please post a more detailed transcript of your code and compiler input and
 output.

 hope that helps,
 -Ben

It helped, thank you, but the D/C behaviour looks extremely strange to me: 1) Declare 'static int b=1234' in C and 'extern (C) int b' in the main D program. Then you can compile and link without errors. No 2nd D file needed, compiler and linker keep quiet and the trap is wide open. Variable b is silently duplicated for the scope of D and initialized with 0, while b is still available as a global C variable and just not visible to D. 2) Declare 'int b=1234' in C w/o 'static' then you must move your 'extern (C) int b' declaration to another file and, amazingly, keep it unlinked as you have suggested before. The dmd docs are mentioning: "While this is not the most elegant looking method ...". I can only agree to that, no more to say.
 ps - this thread should probably belong on digitalmars.D.learn.

Not sure about this, but I have just 'learned' that it is probably not the best idea to start using D in something like life support systems, aircrafts, etc., anytime soon.
Apr 14 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
It helped, thank you, but the D/C behaviour looks
extremely strange to me:

1) Declare 'static int b=1234' in C and 'extern (C) int b'
in the main D program. Then you can compile and link
without errors. No 2nd D file needed, compiler and linker
keep quiet and the trap is wide open. Variable b is silently
duplicated for the scope of D and initialized with 0, while b
is still available as a global C variable and just not visible
to D.

the "b"s are totally separate. It's like having two C files with "static int b" - they are unrelated symbols.
2) Declare 'int b=1234' in C w/o 'static' then you must
move your 'extern (C) int b' declaration to another file
and, amazingly, keep it unlinked as you have suggested
before. The dmd docs are mentioning:
"While this is not the most elegant looking method ...".
I can only agree to that, no more to say.

The confusion comes from extern meaning slightly different things in C and D. It is annoying but once you trip over it and find the solution you tend to remember (at least I find I haven't forgotten that extern dance).
 ps - this thread should probably belong on digitalmars.D.learn.

Not sure about this, but I have just 'learned' that it is probably not the best idea to start using D in something like life support systems, aircrafts, etc., anytime soon.

Too bad your initial experience seems to have spoiled your fun with (or trust in) D. I hope you continue to give it a chance.
Apr 14 2005
parent "Bob W" <nospam aol.com> writes:
"Ben Hinkle" <Ben_member pathlink.com> wrote in message 
news:d3nbss$2bm8$1 digitaldaemon.com...
 the "b"s are totally separate. It's like having two C files with "static 
 int b"
 - they are unrelated symbols.

I know, that is what I should have recognized earlier (or maybe someone in the forum reading my posts). But the 'static' slipped into my C code while trying to find a way to get D to recognize my C globals. One of your previous posts contained a link to a D doc page which would have been sufficient to give me a clue how to treat D's desire for exotic linking, but I just kept skipping over the 'static' while looking on the wrong spots for the wrong things.
 The confusion comes from extern meaning slightly different things in C and 
 D. It
 is annoying but once you trip over it and find the solution you tend to 
 remember
 (at least I find I haven't forgotten that extern dance).

You can be absolutely sure that I'll remember this (unless Walter comes up with a polished dmd 1.0) and thank you again for your info.
 Too bad your initial experience seems to have spoiled your fun with
 (or trust in) D.

Fun is still there, although it briefly diminishes after time consuming tasks. Trust is moderate, because in several other occasions a genuine D flaw was the reason behind strange program behaviour. But considering the alpha version, things could be much worse.
 I hope you continue to give it a chance.

I'll have to. After all neither C++ nor Java (C#) are matching my taste. C is kept in its medieval state for mainly legacy reasons and several others seem to be dying shortly after they have surfaced. Yes, I'll keep watching D's progress ...
Apr 15 2005