View mode: basic / threaded / horizontal-split · Log in · Help
January 31, 2005
extern(C) and data symbols
Is there a way to get access to a data symbol defined in a C library? I'm on 
Linux and I've tried
 extern (C) int foo;
or
 export int foo;
but I can't seem to get ahold of the symbol. The linker complains I'm 
changing the definition. So for now my only workaround is to define a small 
C file with

extern int foo;
int getFoo() {
return foo;
}

and then put
 extern (C) int getFoo();
in my D code and call that whenever I need foo. Is there a better way?

thanks,
-Ben
January 31, 2005
Re: extern(C) and data symbols
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message
news:ctk9og$ch7$1@digitaldaemon.com...
> Is there a way to get access to a data symbol defined in a C library? I'm
on
> Linux and I've tried
>   extern (C) int foo;
> or
>   export int foo;
> but I can't seem to get ahold of the symbol. The linker complains I'm
> changing the definition. So for now my only workaround is to define a
small
> C file with
>
> extern int foo;
> int getFoo() {
>  return foo;
> }
>
> and then put
>   extern (C) int getFoo();
> in my D code and call that whenever I need foo. Is there a better way?

Sure. Declare it in a D module, then do not link in that module. That's how
std.c.stdio works for the globals stdin, stdout, etc.
February 01, 2005
Re: extern(C) and data symbols
"Walter" <newshound@digitalmars.com> wrote in message 
news:ctko8r$1noa$1@digitaldaemon.com...
>
> "Ben Hinkle" <ben.hinkle@gmail.com> wrote in message
> news:ctk9og$ch7$1@digitaldaemon.com...
>> Is there a way to get access to a data symbol defined in a C library? I'm
> on
>> Linux and I've tried
>>   extern (C) int foo;
>> or
>>   export int foo;
>> but I can't seem to get ahold of the symbol. The linker complains I'm
>> changing the definition. So for now my only workaround is to define a
> small
>> C file with
>>
>> extern int foo;
>> int getFoo() {
>>  return foo;
>> }
>>
>> and then put
>>   extern (C) int getFoo();
>> in my D code and call that whenever I need foo. Is there a better way?
>
> Sure. Declare it in a D module, then do not link in that module. That's 
> how
> std.c.stdio works for the globals stdin, stdout, etc.
>

ah. that worked. I was expecting "extern" to behave like it does in C/C++ 
wrt data - ie it becomes a storage-class attribute instead of a linkage-type 
attribute. That was why I tried various combinations of export as well. As 
it stands I'm still going to have to have two files since my original file 
had function definitions that I need to include in the link command and 
these extern data declarations that I now need to exclude from the link 
command. So it looks like at least I'll avoid having a C file in there but 
still it seems too bad that
1) extern applied to data will confuse C/C++ programmers
2) there doesn't seem to be any way to say in the source file the D 
equivalent to the C/C++ meaning.
It doesn't make me feel warm and fuzzy, but then there's a lot of snow 
outside so maybe that has something to do with it.
-Ben
February 01, 2005
Re: extern(C) and data symbols
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message
news:ctmnsr$27ae$1@digitaldaemon.com...
> ah. that worked. I was expecting "extern" to behave like it does in C/C++
> wrt data - ie it becomes a storage-class attribute instead of a
linkage-type
> attribute. That was why I tried various combinations of export as well. As
> it stands I'm still going to have to have two files since my original file
> had function definitions that I need to include in the link command and
> these extern data declarations that I now need to exclude from the link
> command. So it looks like at least I'll avoid having a C file in there but
> still it seems too bad that
> 1) extern applied to data will confuse C/C++ programmers
> 2) there doesn't seem to be any way to say in the source file the D
> equivalent to the C/C++ meaning.
> It doesn't make me feel warm and fuzzy, but then there's a lot of snow
> outside so maybe that has something to do with it.

I ran into this issue a while back when creating std.c.stdio.d, and thought
of the same issues. I decided to leave it as it is because:

1) Few C libraries attempt to use global variables as part of their API.
It's also considered bad form to do it. Nevertheless, it does happen.

2) A D module that only serves as an interface to C code rarely has a need
to define its own code, so it rarely needs to be linked in.

3) Combining 1) and 2) means the issue comes up only rarely. Therefore, I
thought it not worth the extra syntax it would need, especially since the
problem has an easy workaround (I should add it to the
www.digitalmars.com/techtips !)

A more troublesome issue was errno, which looks like a global but isn't.
Arrgh.
February 01, 2005
Re: extern(C) and data symbols
Walter wrote:

> I ran into this issue a while back when creating std.c.stdio.d, and thought
> of the same issues. I decided to leave it as it is because:
> 
> 1) Few C libraries attempt to use global variables as part of their API.
> It's also considered bad form to do it. Nevertheless, it does happen.
> 
> 2) A D module that only serves as an interface to C code rarely has a need
> to define its own code, so it rarely needs to be linked in.

One example of such an "exception" is libSDL, which uses macros in the 
header files. At least for SDL_main, SDL_BlitSurface and SDL_LoadBMP...


Some can be covered with alias, but some require functions to replace 
the macros. And where there are functions, there is code. (and objects)

> /* Convenience macro -- load a surface from a file */
> #define SDL_LoadBMP(file)	SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)

Thus: libSDL_d.a and libSDLmain_d.a, with the D wrapper code.


But it's all SDL's fault. GLUT does the same thing, without any macros.
Which, incidentally, also makes it (GLUT) a lot easier to use from D...

And if someone says "but Windows and Linux doesn't need a custom
SDLmain" one more time, they're gonna get whacked upside da head :-)

--anders
February 01, 2005
Re: extern(C) and data symbols
> 2) A D module that only serves as an interface to C code rarely has a need
> to define its own code, so it rarely needs to be linked in.

In my case it was macros defined by X11's header files that are just so 
pervasive in C/C++ code that I translated them to D. So now I have a D file 
for the macros and a D file for the "pure" interface. It isn't unreasonable 
to keep those separate, though, so it isn't a disaster.

-Ben
February 01, 2005
Re: extern(C) and data symbols
"Anders F Björklund" <afb@algonet.se> wrote in message
news:ctnkta$25r$1@digitaldaemon.com...
> Some can be covered with alias, but some require functions to replace
> the macros. And where there are functions, there is code. (and objects)

Yes. What you can do there is import a special "sdlextern.d" module into
sdl.d so the user of the module never has to worry about it. Phobos does
just this in std.c.linux.linux.
February 01, 2005
Re: extern(C) and data symbols
Walter wrote:

>>Some can be covered with alias, but some require functions to replace
>>the macros. And where there are functions, there is code. (and objects)
> 
> Yes. What you can do there is import a special "sdlextern.d" module into
> sdl.d so the user of the module never has to worry about it. Phobos does
> just this in std.c.linux.linux.

I'm not sure that would work in this case? Since there is no original 
code, the only thing that exists in the C libraries symbol exports is
"SDL_LoadBMP_RW" - the SDL_LoadBMP symbol is undefined (just a macro).

So in order to have a function to call, I need to implement it in D.
And when I do, I get object code for the function wrapper (D) code ?
And this code has to be linked in somehow, I used an extra library...

Hopefully, the function will be easy to inline in the release version.

--anders
February 02, 2005
Re: extern(C) and data symbols
"Anders F Björklund" <afb@algonet.se> wrote in message
news:ctolf7$13ui$1@digitaldaemon.com...
> Walter wrote:
>
> >>Some can be covered with alias, but some require functions to replace
> >>the macros. And where there are functions, there is code. (and objects)
> >
> > Yes. What you can do there is import a special "sdlextern.d" module into
> > sdl.d so the user of the module never has to worry about it. Phobos does
> > just this in std.c.linux.linux.
>
> I'm not sure that would work in this case? Since there is no original
> code, the only thing that exists in the C libraries symbol exports is
> "SDL_LoadBMP_RW" - the SDL_LoadBMP symbol is undefined (just a macro).
>
> So in order to have a function to call, I need to implement it in D.
> And when I do, I get object code for the function wrapper (D) code ?
> And this code has to be linked in somehow, I used an extra library...
>
> Hopefully, the function will be easy to inline in the release version.

Put the functions that generate code into sdl.d. Put the 'extern'
declarations in sdlextern.d. In sdl.d, import sdlextern.d, but do not link
in sdlextern.obj. You can see this at work in std.c.linux.linux.
February 02, 2005
Re: extern(C) and data symbols
>1) Few C libraries attempt to use global variables as part of their API.
>It's also considered bad form to do it. Nevertheless, it does happen.

I just bumped into another situation where I had to link in a translated C
header: _init_MyStruct in the data segment. In other words if the C header
declares a struct and I put that definition in my D module I need to link in the
module since otherwise the linker can't find any initialization values for the
struct. Since that stuff isn't part of the C library it has to come from D.

So I have to add the struct definitions to the same file that has all the
translated macros. It's getting header to read those modules since they have
function and variable declarations in one file and data structures and macros in
another. Compared to the C header it seems less ideal.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home