digitalmars.D - Clarification needed on export/extern
- Jarrett Billingsley (39/39) Feb 21 2005 I've been having some trouble accessing an exported struct in a premade ...
- John Demme (17/76) Feb 21 2005 exporter.d:
- Derek Parnell (35/115) Feb 21 2005 By putting the struct definition into main.d, when you define "extern A ...
- Jarrett Billingsley (2/2) Feb 24 2005 The problem is that this struct is defined in a lib that was compiled wi...
- Ben Hinkle (24/26) Feb 24 2005 I think this has come up a couple times recently. Here's what you should...
- Jarrett Billingsley (2/2) Feb 24 2005 Thanks! That did the trick. Now I just have to deal with a memory acce...
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?
Feb 21 2005
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?
Feb 21 2005
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
Feb 21 2005
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.
Feb 24 2005
"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.
Feb 24 2005
Thanks! That did the trick. Now I just have to deal with a memory access violation in another, unrelated function :P
Feb 24 2005









Derek Parnell <derek psych.ward> 