www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Troubleshooting Linker error (Symbol Undefined)

reply "Jesse Phillips" <jessekphillips+D gmail.com> writes:
I'm trying to identify what change has resulted in getting the 
error:

     Error 42: Symbol Undefined _VarCmp 16

I was doing my not so routine updates for the Juno Class 
Libraries. This symbol is the VARIANT compare function provided 
by oleaut32.lib on Windows. It is a very nice function and has 
been used in Juno for some time. I tracked down the most recent 
working commit and compiler. The only signature changed made was 
const parameters (reverting this did not help). All other changes 
were needed in one form or another to compile in the newer dmd 
versions.

Using the last known working compiler I attempted a reduced test 
to see if I can narrow it down as a compiler/linker bug/change. 
What I ended up with was a test case which exhibited the same 
behavior on this known working compiler (2.057/2.058).

http://dpaste.dzfl.pl/233d037d

This is not intended to run, I've changed the VARIANT definition 
to reduce dependencies. Hopefully it is the same size, but I did 
not make much effort. I've tried different export types, and 
using pointers instead of ref.

This obviously won't link in Linux, but otherwise any suggestions?
Sep 30 2012
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 10/1/12, Jesse Phillips <jessekphillips+D gmail.com> wrote:
 snip

1. The import lib shipped with DMD is outdated and is missing that symbol (http://d.puremagic.com/issues/show_bug.cgi?id=6625) 2. The actual function has C linkage (STDAPI in WinAPI headers Find oleaut32.dll in your Windows folder, and run implib on it: $ implib oleaut32.lib oleaut32.dll /s Put the import lib in the same folder as the project and change linkage to extern(C). It works for me this way. Btw, to verify linkage you can always search the function name on google, find the MSDN page (http://msdn.microsoft.com/en-us/library/windows/desktop/ms221006%28v=vs.85%29.aspx), under requirement it says "Header - OleAuto.h". Those headers are usually here (you'd need to install the Windows SDK though): C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include In OleAuto.h VarCmp has STDAPI linkage, which is a macro to extern "C", defined in BaseTyps.h.
Sep 30 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 10/1/12, Jesse Phillips <jessekphillips+D gmail.com> wrote:
      Error 42: Symbol Undefined _VarCmp 16

P.S. as soon as pointers are involved you don't need the full type info of such a parameter to debug linker errors, so you can cut down on code when reducing. For example if you had to match this C function but are getting linker errors: extern "C" void test(SomeType*); You can prototype this in D as: extern(C) void test(void*); You will still get the same linker error, but you won't have to insert the definition of "SomeType".
Sep 30 2012
prev sibling next sibling parent "Jesse Phillips" <Jessekphillips+D gmail.com> writes:
On Monday, 1 October 2012 at 05:04:32 UTC, Andrej Mitrovic wrote:

 Find oleaut32.dll in your Windows folder, and run implib on it:
 $ implib oleaut32.lib oleaut32.dll /s

Thanks, I'll to play with this more because my first attempt did not resolve the issue and instead has resulted in even more missing symbols. I didn't change export type or anything else so we'll see.
Oct 01 2012
prev sibling next sibling parent "Richard Webb" <webby beardmouse.org.uk> writes:
On Monday, 1 October 2012 at 15:22:20 UTC, Jesse Phillips wrote:
 On Monday, 1 October 2012 at 05:04:32 UTC, Andrej Mitrovic 
 wrote:

 Find oleaut32.dll in your Windows folder, and run implib on it:
 $ implib oleaut32.lib oleaut32.dll /s

Thanks, I'll to play with this more because my first attempt did not resolve the issue and instead has resulted in even more missing symbols. I didn't change export type or anything else so we'll see.

From what i recall, i think i worked around this issue by using coffimplib.exe on the version of oleaut32.lib from the platform sdk, rather than trying to generate a lib from the dll.
Oct 01 2012
prev sibling next sibling parent "Jesse Phillips" <jessekphillips+D gmail.com> writes:
On Monday, 1 October 2012 at 05:04:32 UTC, Andrej Mitrovic wrote:
 Find oleaut32.dll in your Windows folder, and run implib on it:
 $ implib oleaut32.lib oleaut32.dll /s

 Put the import lib in the same folder as the project and change
 linkage to extern(C). It works for me this way.

Thank you, making these changes did do the trick, bunches of linkages changes needed in the Juno library though... and I wonder how many more I won't find just from compiling the lib... Still very confused why it ever compiled. Oh well.
Oct 01 2012
prev sibling next sibling parent "Jesse Phillips" <jessekphillips+D gmail.com> writes:
I've made the changes needed to get past the linker error, but 
have run into an Access Violation when using CoInitializeEx

Once again I've returned to 2.057 (without changing ole32.lib) 
and this will compile and run.

pragma(lib, "ole32.lib");

extern(Windows)
int CoInitializeEx(void*, uint dwCoInit);

void main() {
      CoInitializeEx(null, 0x2);
}

So while this function is also defined as STDAPI in ObjBase.h it 
is working with windows linkage. Fastforward to dmd 2.060 with 
the a library update. The code does not link. I change it to 
extern(C) and linking is fine. However run-time is now an access 
violation.

So I'm not really sure what I'm should be doing with this. And 
Richard, I'm not having different results with coffimplib 
generated library.

When are we getting coff support? Thanks all.
Oct 01 2012
prev sibling next sibling parent "Richard Webb" <webby beardmouse.org.uk> writes:
I haven't tried to use DMD 2.060 yet, will see if i've got time 
later.
Oct 02 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 10/2/12, Jesse Phillips <jessekphillips+D gmail.com> wrote:
 I've made the changes needed to get past the linker error

I'm sorry, I was completely wrong about STDAPI being extern(C). I saw EXTERN_C and immediately thought this was the calling convention, it's not: #define STDAPI EXTERN_C HRESULT STDAPICALLTYPE #define STDAPICALLTYPE __stdcall So this is actually extern(Windows). Linker errors persist when using implib, but when using coffimplib on an existing COFF import library it will link and work at runtime. Here's one I made just now: https://dl.dropbox.com/u/9218759/Ole32_dmd.lib It works for me with this: pragma(lib, "Ole32_dmd.lib"); extern(Windows) int CoInitializeEx(void*, uint dwCoInit); void main() { CoInitializeEx(null, 0x2); }
Oct 02 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 10/2/12, Jesse Phillips <jessekphillips+D gmail.com> wrote:
 Thank you, making these changes did do the trick

As mentioned in the other thread I was wrong, it's extern(Windows), but implib produced an import lib which didn't quite work. coffimplib does the trick though.
Oct 02 2012
prev sibling parent "Jesse Phillips" <jessekphillips+D gmail.com> writes:
On Tuesday, 2 October 2012 at 09:48:00 UTC, Andrej Mitrovic wrote:
 I'm sorry, I was completely wrong about STDAPI being extern(C). 
 I saw
 EXTERN_C and immediately thought this was the calling 
 convention, it's
 not:

 #define STDAPI                  EXTERN_C HRESULT STDAPICALLTYPE
 #define STDAPICALLTYPE          __stdcall

 So this is actually extern(Windows).

 Linker errors persist when using implib, but when using 
 coffimplib on
 an existing COFF import library it will link and work at 
 runtime.

 Here's one I made just now: 
 https://dl.dropbox.com/u/9218759/Ole32_dmd.lib
 It works for me with this:

 pragma(lib, "Ole32_dmd.lib");

 extern(Windows)
 int CoInitializeEx(void*, uint dwCoInit);

 void main()
 {
      CoInitializeEx(null, 0x2);
 }

Thank you, it does work, and I figured out why my coffimplib didn't work. I forgot to rename it, so I moved it as out.lib :( I'm going to go write up some docs tonight.
Oct 02 2012