Thread overview
Importing global variables from a library
Dec 09, 2004
Lionello Lunesu
Dec 09, 2004
John Reimer
Dec 09, 2004
John Reimer
Dec 10, 2004
Lionello Lunesu
Sep 28, 2021
kshmirko
Sep 28, 2021
max haughton
Dec 10, 2004
Lionello Lunesu
December 09, 2004
Hi...

I've made an attempt to port disp.h (from dmc) to D (see a previous post of mine). The functions work fine, but the varbiables don't get imported. Specifically:

extern (C)  int
  disp_numrows,
  disp_numcols,
  disp_cursorrow,
  disp_cursorcol;

I get no linker errors when I try to use these variables, but their value is always 0. The name doesn't even matter. It seems "extern (C) int something;" actually declares that variable instead of importing it from a library.

What am I doing wrong?

-- 
L.

-- Get the root certificate at https://www.cacert.org/


December 09, 2004
On Thu, 09 Dec 2004 16:28:52 +0200, Lionello Lunesu wrote:

> Hi...
> 
> I've made an attempt to port disp.h (from dmc) to D (see a previous post of mine). The functions work fine, but the varbiables don't get imported. Specifically:
> 
> extern (C)  int
>   disp_numrows,
>   disp_numcols,
>   disp_cursorrow,
>   disp_cursorcol;
> 
> I get no linker errors when I try to use these variables, but their value is always 0. The name doesn't even matter. It seems "extern (C) int something;" actually declares that variable instead of importing it from a library.
> 
> What am I doing wrong?

First declare them in a their own module, then import that module into your project, but don't compile and link that module.  If you compile the declaring module, you end up making a new set of global variables and the external library ones won't be accessible.

So do something like this:

// file: disp.d

module disp;

extern(C) {
	disp_numrows,
	disp_numcols,
	disp_cursorrow,
	disp_cursorcol,
}

// end of disp.d

-------------------------------

// file: project.d

module project.d;

import disp;

int main()
{
// do whatever
}

// end of project.d

-------------------------------

Now compile project.d.  Do not compile disp.d.  It merely provides the names of the external symbols it needs to access.  link in the appropriate library that contains the actual global variables you need to access.  It should now work as planned.  This is actually much the same as the "interface" module idea discussed in another newsgroup post.

Have a look at phobos for another example of this (std.c.linux.linuxextern).  I was confused about this same issue at one point.

Later,

John

John
December 09, 2004
On Thu, 09 Dec 2004 14:28:03 -0800, John Reimer wrote:

> extern(C) {
> 	disp_numrows,
> 	disp_numcols,
> 	disp_cursorrow,
> 	disp_cursorcol,
> }

Okay... a typed a bit hastily.  Pardon me!

I meant to say:

extern(C) {
	int disp_numrows;
	int disp_numcols;
	int disp_cursorrow;
	int disp_cursorcol;
}

Your way of declaring extern with commas should work as well.
December 10, 2004
Isn't it a bug that "extern (C) int something;" actually declares the variable, instead of importing it?

Come to think of it, something is missing in the language definition:

* With functions it's obvious that "extern (C) int func();" is a 'forward' and the function should be imported.

* With variables, "extern (C) int bla;" it's not clear whether the variable should be imported or is declared (and should be exported with C linkage).

True? Or nonsense?

Lionello.


December 10, 2004
Thanks for your advice. It helps if I don't compile the disp.d. I guess it's acting like a C header file now :-/

 > extern(C) {
> int disp_numrows;
> int disp_numcols;
> int disp_cursorrow;
> int disp_cursorcol;
> }

I still can't get it to import those 4 integers. I'm starting to think they're simply not available in the library, because in the same disp.d there's a declaration of an extern structure:

// from disp.h: extern disp_t __cdecl disp_state;
extern (C) disp_t  disp_state;

This one is working and correctly imported. Even if I put it in my compiled module: it doesn't declare a new variable but (correctly) imports it from the C library. However, if I change the name, it doesn't import the variable but declares it.

Lionello.


September 28, 2021
On Friday, 10 December 2004 at 10:03:24 UTC, Lionello Lunesu wrote:
> Thanks for your advice. It helps if I don't compile the disp.d. I guess it's acting like a C header file now :-/
>
>  > extern(C) {
>> int disp_numrows;
>> int disp_numcols;
>> int disp_cursorrow;
>> int disp_cursorcol;
>> }
>
> I still can't get it to import those 4 integers. I'm starting to think they're simply not available in the library, because in the same disp.d there's a declaration of an extern structure:
>
> // from disp.h: extern disp_t __cdecl disp_state;
> extern (C) disp_t  disp_state;
>
> This one is working and correctly imported. Even if I put it in my compiled module: it doesn't declare a new variable but (correctly) imports it from the C library. However, if I change the name, it doesn't import the variable but declares it.
>
> Lionello.

For your question, just add __gshared attribute
extern __gshared int a, b, c;


September 28, 2021
On Tuesday, 28 September 2021 at 09:52:35 UTC, kshmirko wrote:
> On Friday, 10 December 2004 at 10:03:24 UTC, Lionello Lunesu wrote:
>> [...]
>
> For your question, just add __gshared attribute
> extern __gshared int a, b, c;

I was three years old when the message you are replying to was posted, please be careful.