www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - linker error

reply "lodo" <lodovico giaretart.net> writes:
When I try to compile the code below I get this error:
  prova00.obj(prova00)
  Error 42: Symbol Undefined _D6prova013implementThisFZi
  --errorlevel 1

This is my code:

File prova0.d:
import std.stdio;
int implementThis();
void callThis()
{
	writefln("%d",implementThis());
}

File prova00.d:
import prova0;
int implementThis()
{
	return 42;
}
void main()
{
	callThis();
}

Can someone help me, please?
Jul 09 2012
parent reply "Tobias Pankrath" <tobias pankrath.net> writes:
On Monday, 9 July 2012 at 08:45:25 UTC, lodo wrote:
 When I try to compile the code below I get this error:
  prova00.obj(prova00)
  Error 42: Symbol Undefined _D6prova013implementThisFZi
  --errorlevel 1

 This is my code:

 File prova0.d:
 import std.stdio;
 int implementThis();
 void callThis()
 {
 	writefln("%d",implementThis());
 }

 File prova00.d:
 import prova0;
 int implementThis()
 {
 	return 42;
 }
 void main()
 {
 	callThis();
 }

 Can someone help me, please?
The module gets mangled into the function name. So the implementThis that you declare in prova0.d is different from the one you implement in prova00.d. You could use externC to prevent the mangling.
Jul 09 2012
parent reply "lodo" <lodovico giaretart.net> writes:
On Monday, 9 July 2012 at 09:15:52 UTC, Tobias Pankrath wrote:
 On Monday, 9 July 2012 at 08:45:25 UTC, lodo wrote:
 When I try to compile the code below I get this error:
 prova00.obj(prova00)
 Error 42: Symbol Undefined _D6prova013implementThisFZi
 --errorlevel 1

 This is my code:

 File prova0.d:
 import std.stdio;
 int implementThis();
 void callThis()
 {
 	writefln("%d",implementThis());
 }

 File prova00.d:
 import prova0;
 int implementThis()
 {
 	return 42;
 }
 void main()
 {
 	callThis();
 }

 Can someone help me, please?
The module gets mangled into the function name. So the implementThis that you declare in prova0.d is different from the one you implement in prova00.d. You could use externC to prevent the mangling.
Now it works! I added "extern(C)" to both declaration and implementation of "implementThis". Thank you, Tobias.
Jul 09 2012
parent reply "Tobias Pankrath" <tobias pankrath.net> writes:
 Now it works! I added "extern(C)" to both declaration and 
 implementation of "implementThis". Thank you, Tobias.
No problem. What are you planning to do anyway? It seems that you want to have loose coupling between the modules since you don't just import the prove00.d. Using the linker for this seems rather fragile and I don't think this approach will scale with multiple implementations. Using D you could consider doing something along these lines: A.d: void callThis(alias callee, Args ...) { callee(Args); } B.d: void implThis(string foo) { writeln(foo); } callThis!(implThis)("bar"); Not tested.
Jul 09 2012
next sibling parent "lodo" <lodovico giaretart.net> writes:
Let suppose I'm writing a library for Win32 applications, called 
"mylibrary".
A program, called "UserProgram", that uses this library would be 
like this:

UserProgram.d:
import mylibrary;
import std.c.windows.windows;
int WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR cmdLine,int 
cmdShow)
{
     //initialization of mylibrary
     //usercode
     //de-initialization of mylibrary
}

What I was trying to do with prova0 and prova00 was something 
like this:

mylibrary.d:
public import std.c.windows.windows;
extern(C) void UserMain();
int WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR cmdLine,int 
cmdShow)
{
     //initialization of mylibrary
     UserMain();
     //de-initialization of mylibrary
}
UserProgram.d:
import mylibrary;
extern(C) void UserMain()
{
     //usercode
}

This second way would be much cleaner for the user of the library.
P.S.: Sorry for my english: I know I'm not very good in it.
Jul 10 2012
prev sibling parent "lodo" <lodovico giaretart.net> writes:
Let suppose I'm writing a library for Win32 applications called 
"mylibrary".
The code of a program, called "UserProgram", that uses this 
library would be like this:

UserProgram.d:
import mylibrary;
import std.c.windows.windows;
int WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR cmdLine,int 
cmdShow)
{
     //initialization of mylibrary
     //user code
     //de-initialization of mylibrary
}

What i was trying to do with prova0 and prova00 was calling 
WinMain inside mylibrary, doing initialization and then call a 
user-defined procedure with only the user-code. Then, doing 
de-initialization and returning from WinMain inside the libary. 
In this way, the user have to define only his code. Something 
like this:

mylibrary.d:
public import std.c.windows.windows;
extern(C) UserMain();
int WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR cmdLine,int 
cmdShow)
{
     //initialization of mylibrary
     UserMain();
     //de-initialization of mylibrary
}
UserProgram.d:
import mylibrary;
extern(C) void UserMain()
{
     //user code
}

I think this second way is much cleaner for the user and prevent 
him from using mylibrary without correct initialization and 
de-initialization.
I can't use static module initializers for this task because i 
need the parameters of WinMain for the initialization.
P.S.: Sorry for my english, I know I'm not very good in it.
Jul 10 2012