Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

XS Library Compilation Problems: Linker Error

by talwyn (Monk)
on Nov 09, 2003 at 17:27 UTC ( [id://305695]=perlquestion: print w/replies, xml ) Need Help??

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

I copied the code from Dave Roth's book Win32: the standard Extensions for a handcoded extension in c++ to see how it all works. The code is from Chapter 10, pg 527 However being a relative newbie I have a few linking errors that don't make sense to me. I tried defining all the compile options my perl had and that did remove several warnings and two link errors but more remain.

THis type of XS extension is also discussed in the ADvanced Perl Programming book on ppg 353-357. This is not Xsub type code.

  • OS: WIndows XP professional
  • Compiler MS Visual Studio .net c++
  • Perl 5.8.0

I have set the include and lib paths to c:\Perl\bin; C:\Perl\lib\CORE.

Actual error messages and the C++ source I'm working with posted below:


Error Messages

test.c warning LNK4070: /OUT:Test.dll directive in .EXP differs from o +utput filename 'Debug/test.c.dll'; ignoring directive test.c error LNK2019: unresolved external symbol _Perl_sv_2mortal refe +renced in function "void __cdecl ExtensionAddNumbers(struct interpret +er *,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@PAUcv@@@ +Z) test.c error LNK2019: unresolved external symbol _Perl_newSViv referen +ced in function "void __cdecl ExtensionAddNumbers(struct interpreter +*,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@PAUcv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_croak_nocontext + referenced in function "void __cdecl ExtensionAddNumbers(struct inte +rpreter *,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@PAU +cv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_Tstack_base_ptr + referenced in function "void __cdecl ExtensionAddNumbers(struct inte +rpreter *,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@PAU +cv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_Tmarkstack_ptr_ +ptr referenced in function "void __cdecl ExtensionAddNumbers(struct i +nterpreter *,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@ +PAUcv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_Tstack_sp_ptr r +eferenced in function "void __cdecl ExtensionAddNumbers(struct interp +reter *,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@PAUcv +@@@Z) test.c error LNK2019: unresolved external symbol _Perl_get_context ref +erenced in function "void __cdecl ExtensionAddNumbers(struct interpre +ter *,struct cv *)" (?ExtensionAddNumbers@@YAXPAUinterpreter@@PAUcv@@ +@Z) test.c error LNK2019: unresolved external symbol _Perl_sv_2iv referenc +ed in function "long __cdecl ExtractLongFromSV(struct sv *)" (?Extrac +tLongFromSV@@YAJPAUsv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_sv_setsv_flags +referenced in function "void __cdecl ExtensionGetFileSizes(struct int +erpreter *,struct cv *)" (?ExtensionGetFileSizes@@YAXPAUinterpreter@@ +PAUcv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_Isv_undef_ptr r +eferenced in function "void __cdecl ExtensionGetFileSizes(struct inte +rpreter *,struct cv *)" (?ExtensionGetFileSizes@@YAXPAUinterpreter@@P +AUcv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_sv_catpvn_flags + referenced in function "void __cdecl ExtensionGetFileSizes(struct in +terpreter *,struct cv *)" (?ExtensionGetFileSizes@@YAXPAUinterpreter@ +@PAUcv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_sv_2pv_flags re +ferenced in function "void __cdecl ExtensionGetFileSizes(struct inter +preter *,struct cv *)" (?ExtensionGetFileSizes@@YAXPAUinterpreter@@PA +Ucv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_newSVpv referen +ced in function "void __cdecl ExtensionGetFileSizes(struct interprete +r *,struct cv *)" (?ExtensionGetFileSizes@@YAXPAUinterpreter@@PAUcv@@ +@Z) test.c error LNK2019: unresolved external symbol _Perl_Isv_yes_ptr ref +erenced in function "void __cdecl boot_Win32__Test(struct interpreter + *,struct cv *)" (?boot_Win32__Test@@YAXPAUinterpreter@@PAUcv@@@Z) test.c error LNK2019: unresolved external symbol _Perl_newXS reference +d in function "void __cdecl boot_Win32__Test(struct interpreter *,str +uct cv *)" (?boot_Win32__Test@@YAXPAUinterpreter@@PAUcv@@@Z) test.c fatal error LNK1120: 15 unresolved externals
Source test.cpp
// test.c.cpp : Defines the entry point for the dll application. // #ifdef __BORLANDC__ typedef wchar_t wctype_t; #endif #define EMBED #define WIN32 #define HAVE_DES_FCRYPT #define MULTIPLICITY #define PERL_IMPLICIT_CONTEXT #define PERL_IMPLICIT_SYS #define PERL_NO_GET_CONTEXT #define PERL_POLLUTE #define USE_ITHREADS #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> #include <math.h> #include "stdafx.h" #if defined (__cplusplus) && !defined( PERL_OBJECT ) extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #if defined (__cplusplus) && !defined( PERL_OBJECT ) } #endif // Global Variables HINSTANCE ghInstance = NULL; DWORD gdwThreads = 0; #if PERL_VERSION == 6 && !defined( PERL_OBJECT ) #ifndef USE_THREADS #define PERL_ARG_PROTO PerlInterpreter* my_perl +, #define PERL_ARG_ONLY_PROTO PerlInterpreter* my_per +l #define PERL_ARG my_perl, #define PERL_ARG_ONLY my_perl #else #define PERL_ARG_PROTO pTHXo_ #define PERL_ARG_ONLY_PROTO perl_thread *thr #define PERL_ARG aTHXo_ #define PERL_ARG_ONLY aTHXo #endif #endif #ifdef PERL_OBJECT #define PERL_ARG_PROTO CPerl *pPerl, #define PERL_ONLY_ARG_PROTO CPerl *pPerl #define PERL_ARG pPerl, #define PERL_ARG_ONLY pPerl #else #define PERL_ARG_PROTO #define PERL_ONLY_ARG_PROTO #define PERL_ARG #define PERL_ONLY_ARG #endif long ExtractLongFromSV ( PERL_ARG_PROTO SV* pSV ); XS ( ExtensionAddNumbers ){ dXSARGS; long lNum1; long lNum2; long lSum; SV* pSV; if ( items != 2 ) { croak ( "Usage : $Sum = Win32::Test::AddNumbers ( $First, $Sec +ond ) "); } pSV = ST (0); lNum1 = ExtractLongFromSV (PERL_ARG pSV ); pSV = ST (1) ; lNum2 = ExtractLongFromSV (PERL_ARG pSV ); lSum = lNum1 + lNum2; pSV = newSViv (lSum); ST(0) = sv_2mortal (pSV); XSRETURN (1); } long ExtractLongFromSV ( PERL_ARG_PROTO SV* pSV ){ dXSARGS; long lValue = 0; if ( SvIOK (pSV) ) { lValue = SvIV ( pSV); } return (lValue); } typedef struct { char m_szPath[256]; DWORD m_dwSize; } FileStruct; XS ( ExtensionGetFileSizes ){ dXSARGS; FileStruct File; WIN32_FIND_DATA fileFind; HANDLE hSearch; SV *pSV = newSVpv("", 0); char *pszPath = NULL; int iTotal = 0; BOOL bContinue = TRUE; unsigned int uiLength = 0; if ( items != 2 ) { croak ( "Usage : $Sum = Win32::Test::GetFileSizes ( $Path, $Da +ta ) "); } pszPath = SvPV ( ST ( 0 ), uiLength ); hSearch = FindFirstFile ( pszPath, &fileFind ); if ( INVALID_HANDLE_VALUE != hSearch ) { while ( bContinue) { if ( ! ( fileFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECT +ORY ) ) { ZeroMemory ( File.m_szPath, sizeof ( File.m_szPath)); strncpy (File.m_szPath, fileFind.cFileName, sizeof ( F +ile.m_szPath ) -1); File.m_dwSize = fileFind.nFileSizeLow; sv_catpvn ( pSV, (char*) &File, sizeof (File) ); iTotal++; } bContinue = FindNextFile ( hSearch, &fileFind ); } FindClose ( hSearch ); } else { pSV = &PL_sv_undef; } ST (0) = sv_2mortal ( newSViv ( iTotal) ); sv_setsv ( ST (1) , pSV ) ; XSRETURN (1); } XS (boot_Win32__Test ) { dXSARGS; char *pszFile= __FILE__; newXS ( "Win32::Test::GetFileSizes", ExtensionGetFileSizes, pszFil +e ); newXS ( "Win32::Test::AddNumbers", ExtensionAddNumbers, __FILE__ ) +; ST (0) = &PL_sv_yes; XSRETURN (1); } BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ){ BOOL bResult = TRUE; switch ( dwReason ){ case DLL_PROCESS_ATTACH: ghInstance = hInstance; break; case DLL_THREAD_ATTACH: gdwThreads++; break; case DLL_THREAD_DETACH: gdwThreads--; break; case DLL_PROCESS_DETACH: break; } return ( bResult ); }

Replies are listed 'Best First'.
Re: XS Library Compilation Problems: Linker Error
by Roger (Parson) on Nov 10, 2003 at 01:05 UTC
    Your DLL needs to link with the Perl58.lib. Check if Perl58.lib is included in the list of libraries. Setting the include and lib path is not enough, that will only let you compile to an object file. But to produce the final DLL, you have to link the object file & libraries as well. To link properly, you have to tell the linker to link with Perl58.lib under C:\Perl\lib\CORE.

    PS. I see that you are using Visual Studio .NET version of the C compiler, not Visual C++ 6 version. I think the .NET version is quite different to the older non .NET version of the Visual C++ compiler, and produces different codes. The .NET compiler generates Just-In-Time opcodes, while the non .NET compiler generates native Machine code.

    Update: forget about the comment on Visual Studio C++ .NET, not relevant to the problem.

      Roger, Thanks for your help. I got it to compile and it works.. sort of. The function call seems to work but the perl test script hangs. Perhaps this is the .Net issue you were talking about? Is there a compatability mode I can set in Visual Studio?

      When only one parameter is passed I get the croak message expected and the script/perl exits properly back to commandline. When both parameters are passed I get the sum printed but either the script, dll, or perl itself hangs and I have to terminate with ^C.

        I think Active Perl 5.8 from ActiveStates was compiled with the non-.NET version of Visual C++ (Visual C++ 6? 7?). Unless you compile your XS with the non-.NET version of Visual C++, it is not going to work properly. 8^(

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://305695]
Approved by Zaxo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (2)
As of 2024-04-26 00:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found