szr has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I've been trying feverishly to get this working for almost two days now. After finding the proper vintage of the MS SDK to match VC6 (which the package seems prepared for), It appears to compile. But I'm getting these linker errors (reformated for readability):
link.exe kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib 
         shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 
         ws2_32.lib  netapi32.lib mpr.lib
         /nologo /subsystem:windows /dll /machine:I386  
         /pdb:.\perl.10xx.release\lanman.pdb /def:.\lanman.def 
         /out:.\perl.10xx.release\lanman.dll         
         /implib:.\perl.10xx.release\lanman.lib /incremental:no 
         "/libpath:C:\Program Files\Microsoft SDK\lib"        
         /libpath:"C:\Perl\lib\core" perl510.lib /opt:nowin98 
         .\perl.10xx.release\access.obj   .\perl.10xx.release\addloader.obj
         .\perl.10xx.release\alert.obj    .\perl.10xx.release\browse.obj
         .\perl.10xx.release\dfs.obj      .\perl.10xx.release\domain.obj
         .\perl.10xx.release\ds.obj       .\perl.10xx.release\eventlog.obj
         .\perl.10xx.release\file.obj     .\perl.10xx.release\get.obj
         .\perl.10xx.release\group.obj    .\perl.10xx.release\handle.obj 
         .\perl.10xx.release\lanman.obj   .\perl.10xx.release\message.obj
         .\perl.10xx.release\misc.obj     .\perl.10xx.release\plmisc.obj
         .\perl.10xx.release\policy.obj   .\perl.10xx.release\reghlp.obj
         .\perl.10xx.release\repl.obj     .\perl.10xx.release\schedule.obj
         .\perl.10xx.release\server.obj   .\perl.10xx.release\service.obj
         .\perl.10xx.release\session.obj  .\perl.10xx.release\share.obj
         .\perl.10xx.release\stat.obj     .\perl.10xx.release\strhlp.obj
         .\perl.10xx.release\termserv.obj .\perl.10xx.release\timeofd.obj
         .\perl.10xx.release\use.obj      .\perl.10xx.release\user.obj
         .\perl.10xx.release\wnetwork.obj .\perl.10xx.release\workst.obj
         .\perl.10xx.release\wstring.obj  .\perl.10xx.release\resource.res

   Creating library .\perl.10xx.release\lanman.lib and object .\perl.10xx.release\lanman.exp
dfs.obj : error LNK2001: unresolved external symbol _NetDfsRename@8
dfs.obj : error LNK2001: unresolved external symbol _NetDfsMove@8
domain.obj : error LNK2001: unresolved external symbol _NetEnumerateTrustedDomains@8
domain.obj : error LNK2001: unresolved external symbol _I_NetGetDCList@16
.\perl.10xx.release\lanman.dll : fatal error LNK1120: 4 unresolved externals
NMAKE : fatal error U1077: 'link.exe' : return code '0x460'
Stop.
I checked inside dfs.cpp and made my way to dfs.h where it only declares those symbols but doesn't define them. E.g: dfs.h:133 XS(XS_NT__Lanman_NetDfsRename); I searched seemingly everywhere but I cannot find where these symbols are supposed to be found. Any help much appreciated.
  • Comment on Compiling Win32::Lanman for ActivePerl 5.10

Replies are listed 'Best First'.
Re: Compiling Win32::Lanman for ActivePerl 5.10
by BrowserUk (Patriarch) on Oct 17, 2008 at 11:09 UTC

    The unresolved symbols are exported by netapi32.dll. However, they are exported without the leading underscores, hence why they are not resolved. This is an indication that they are being called with the wrong calling convention--eg. cdecl rather than system or fastcall.

    Probably the best way of resolving the issue would be to remove the (faulty?) declarations from dfs.h and include the MS distributed header file: LMDFS.h. If that causes other problems--I'm not in a position right now to try my theories--then copy the MS declarations from that file over those in dfs.h and see what happens. You might need to bring across a few #defines as well if you go this route.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thank you all for your responses. To be clear, dfs.cpp does #include <lmdfs.h> And it seems I have goofed slightly in my descrtiption (apologies.) dfs.h has these declarations that seem to corraspond to the linker errors:
      133: XS(XS_NT__Lanman_NetDfsRename); 154: XS(XS_NT__Lanman_NetDfsMove);
      amd domain.h:
      93: XS(XS_NT__Lanman_NetEnumerateTrustedDomains); 111: XS(XS_NT__Lanman_I_NetGetDCList);
      And these "XS" functions are defined. It's the functions they call from within that's the problem: IE: (dfs.cpp:315)
      XS(XS_NT__Lanman_NetDfsRemove) { [...] LastError(NetDfsRemove(entryPath, server, share)); [...] }
      Interestingly, in domain.h, in the comment block directly preceding "XS(XS_NT__Lanman_NetEnumerateTrustedDomains);" it mentioned the following: (reformated slightly for readability.) domain.h:83
      // important: if you need to compile this module, please change the // function prototype in lmaccess.h to the following: // // NTSTATUS NET_API_FUNCTION NetEnumerateTrustedDomains( // IN LPWSTR ServerName OPTIONAL, OUT LPWSTR *DomainNames);
      This is the best clue I've found so far. Ok, so I opened "C:\Program Files\Microsoft SDK\Include\LMAccess.h" and at line 1378 I see:
      NTSTATUS NET_API_FUNCTION NetEnumerateTrustedDomains ( IN LPWSTR ServerName OPTIONAL, OUT LPWSTR *DomainNames );
      So to be sure I went and opened "C:\Program Files\Microsoft Visual Studio\6.0\VC98\Include\LMACCESS.H" and at line 1311 I see:
      NTSTATUS NetEnumerateTrustedDomains ( IN LPWSTR ServerName OPTIONAL, OUT LPWSTR *DomainNames );
      Which appears to be missing the "NET_API_FUNCTION" part. I added "NET_API_FUNCTION" and deleted "perl.10xx.release\domain.obj" and re-ran "vc6 nmake" (vc6 is a batch file that setups the correct environment for vc6) and domain.obj recompiled but I got the same linker errors. Thank for the help so far. The thing I really don't get is that all the unresolved symbols the linker complains about all have leading underscores (ie, _NetDfsRename, _NetDfsMove, _NetEnumerateTrustedDomains, _I_NetGetDCList) but the actual calls in the .cpp files have no underscores (ie, NetDfsRemove, NetDfsMove, NetEnumerateTrustedDomains, I_NetGetDCList), yet other functions like XS(XS_NT__Lanman_NetDfsRename), which calls NetDfsRename, works fine. Any more insight is very much appreciated.
Re: Compiling Win32::Lanman for ActivePerl 5.10
by wol (Hermit) on Oct 17, 2008 at 09:48 UTC
Re: Compiling Win32::Lanman for ActivePerl 5.10
by Anonymous Monk on Oct 17, 2008 at 08:27 UTC
    Where'd you get it?