View mode: basic / threaded / horizontal-split · Log in · Help
February 22, 2005
Clarification needed on export/extern
I've been having some trouble accessing an exported struct in a premade lib 
using the extern keyword, so I tried to recreate the problem I was having, 
and now I'm kind of stuck.  I think I'm just not understanding something 
correctly.

Here's where I am now:


1) I have a file called exporter.d that contains the following code:

struct A
{
   int x,y;
}

static export A a={5,10};

I compile this to an .obj file.  All is well.


2) I have a file called main.d that contains the following code.

import std.stdio;

struct A
{
   int x,y;
}

extern A a;

void main()
{
   writefln(a.x);
}

This program is compiled with the exporter.obj file.


Now: it gives me a linker error saying that it can't find _D4main1aS4main1A, 
which means it's looking for the symbol named "a" in "main" with a type of 
"main.A."  Oookay, I'd really love for it to look for that symbol in another 
file, namely exporter.obj.  I thought that's why I put "extern" in front of 
"A a."

If I change my extern line to something like "extern(D) A a" or 
"extern(Windows) A a" or even "extern() A a," it compiles, links, and runs, 
but prints 0.  It's obviously not linking to the external symbol.

How on earth do I get it to look in exporter.obj for "a"?  I've run 
exporter.obj through libunres and it is in fact exporting its "a," although 
it's called "_D8exporter1aS8exporter1A."  I've tried using a .def file with 
an IMPORTS directive to translate the names, but all it does is give me some 
horrendous linker error about an illegal frame on a start address, and.. I 
don't need that kind of drama.

What am I missing?
February 22, 2005
Re: Clarification needed on export/extern
exporter.d:
module exporter;

struct A
{
	int x,y;
}

A a = {5,10};

main.d:
module main;
import exporter;
import std.stdio;

void main() {
	writefln(a.x);
}

D is not C... not even close.

John

Jarrett Billingsley wrote:
> I've been having some trouble accessing an exported struct in a premade lib 
> using the extern keyword, so I tried to recreate the problem I was having, 
> and now I'm kind of stuck.  I think I'm just not understanding something 
> correctly.
> 
> Here's where I am now:
> 
> 
> 1) I have a file called exporter.d that contains the following code:
> 
> struct A
> {
>     int x,y;
> }
> 
> static export A a={5,10};
> 
> I compile this to an .obj file.  All is well.
> 
> 
> 2) I have a file called main.d that contains the following code.
> 
> import std.stdio;
> 
> struct A
> {
>     int x,y;
> }
> 
> extern A a;
> 
> void main()
> {
>     writefln(a.x);
> }
> 
> This program is compiled with the exporter.obj file.
> 
> 
> Now: it gives me a linker error saying that it can't find _D4main1aS4main1A, 
> which means it's looking for the symbol named "a" in "main" with a type of 
> "main.A."  Oookay, I'd really love for it to look for that symbol in another 
> file, namely exporter.obj.  I thought that's why I put "extern" in front of 
> "A a."
> 
> If I change my extern line to something like "extern(D) A a" or 
> "extern(Windows) A a" or even "extern() A a," it compiles, links, and runs, 
> but prints 0.  It's obviously not linking to the external symbol.
> 
> How on earth do I get it to look in exporter.obj for "a"?  I've run 
> exporter.obj through libunres and it is in fact exporting its "a," although 
> it's called "_D8exporter1aS8exporter1A."  I've tried using a .def file with 
> an IMPORTS directive to translate the names, but all it does is give me some 
> horrendous linker error about an illegal frame on a start address, and.. I 
> don't need that kind of drama.
> 
> What am I missing? 
> 
>
February 22, 2005
Re: Clarification needed on export/extern
On Tue, 22 Feb 2005 00:39:30 -0500, John Demme wrote:

> exporter.d:
> module exporter;
> 
> struct A
> {
> 	int x,y;
> }
> 
> A a = {5,10};
> 
> main.d:
> module main;
> import exporter;
> import std.stdio;
> 
> void main() {
> 	writefln(a.x);
> }
> 
> D is not C... not even close.
> 
> John
> 
> Jarrett Billingsley wrote:
>> I've been having some trouble accessing an exported struct in a premade lib 
>> using the extern keyword, so I tried to recreate the problem I was having, 
>> and now I'm kind of stuck.  I think I'm just not understanding something 
>> correctly.
>> 
>> Here's where I am now:
>> 
>> 1) I have a file called exporter.d that contains the following code:
>> 
>> struct A
>> {
>>     int x,y;
>> }
>> 
>> static export A a={5,10};
>> 
>> I compile this to an .obj file.  All is well.
>> 
>> 2) I have a file called main.d that contains the following code.
>> 
>> import std.stdio;
>> 
>> struct A
>> {
>>     int x,y;
>> }
>> 
>> extern A a;
>> 
>> void main()
>> {
>>     writefln(a.x);
>> }
>> 
>> This program is compiled with the exporter.obj file.
>> 
>> Now: it gives me a linker error saying that it can't find _D4main1aS4main1A, 
>> which means it's looking for the symbol named "a" in "main" with a type of 
>> "main.A."  Oookay, I'd really love for it to look for that symbol in another 
>> file, namely exporter.obj.  I thought that's why I put "extern" in front of 
>> "A a."
>> 
>> If I change my extern line to something like "extern(D) A a" or 
>> "extern(Windows) A a" or even "extern() A a," it compiles, links, and runs, 
>> but prints 0.  It's obviously not linking to the external symbol.
>> 
>> How on earth do I get it to look in exporter.obj for "a"?  I've run 
>> exporter.obj through libunres and it is in fact exporting its "a," although 
>> it's called "_D8exporter1aS8exporter1A."  I've tried using a .def file with 
>> an IMPORTS directive to translate the names, but all it does is give me some 
>> horrendous linker error about an illegal frame on a start address, and.. I 
>> don't need that kind of drama.
>> 
>> What am I missing? 
>> 
>>

By putting the struct definition into main.d, when you define "extern A a;"
it tells the linker to look for the 'a' inside a module called 'main'
rather than 'exporter'. Because the struct was also defined and the 'a' was
defined i the 'exporter' module, that is what it is known as in the obj
file - namely as 'exporter.a'.

To simplify matters, D does away with a lot of these linkage hassles.
Create the exporter.d file as you have (but it doesn't need the "export"
keyword). Then make your main.d file look like this ...

import std.stdio;
import exporter;

void main()
{
    writefln(a.x);
}

I tested this and this is the result I got ...

C:\temp>dmd exporter.d -c

C:\temp>dmd main.d -c

C:\temp>dmd main.obj exporter.obj
C:\DPARNELL\DMD\BIN\..\..\dm\bin\link.exe
main+exporter,,,user32+kernel32/noi;

C:\temp>main
5

Of course, I also used a simpler way too ...

C:\temp>build main
C:\DPARNELL\DMD\BIN\..\..\dm\bin\link.exe
main+exporter,main.exe,,user32+kernel3
2/noi;

C:\temp>main
5

Hope this helps.

-- 
Derek
Melbourne, Australia
22/02/2005 4:49:35 PM
February 24, 2005
Re: Clarification needed on export/extern
The problem is that this struct is defined in a lib that was compiled with C 
linkage.  I need to access this struct.  I can't figure out how.
February 24, 2005
Re: Clarification needed on export/extern
"Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message 
news:cvlhce$21rt$1@digitaldaemon.com...
> The problem is that this struct is defined in a lib that was compiled with 
> C linkage.  I need to access this struct.  I can't figure out how.

I think this has come up a couple times recently. Here's what you should do: 
write a d file that has the definition of the struct but don't link it in. 
For example, say foo.lib has the struct Bar in it then write
foo.d
 extern (C):
 struct BarType {
   int x;
   int y;
 }
 BarType Bar;

then import foo into your regular d code:

main.d
 import foo;
 int main() {
   printf("Bar.x is %d\n",Bar.x);
   return 0;
 }

Now the key is that you don't link in foo.obj:
 dmd -c main.d
 dmd main.obj foo.lib

Or if you use the nifty "build" utility you can tell it to do all that for 
you.
February 25, 2005
Re: Clarification needed on export/extern
Thanks!  That did the trick.  Now I just have to deal with a memory access 
violation in another, unrelated function :P
Top | Discussion index | About this forum | D home