Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | > 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | "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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | "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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
>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.
|
Copyright © 1999-2021 by the D Language Foundation