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: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 PMI'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
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