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.
I have set the include and lib paths to c:\Perl\bin; C:\Perl\lib\CORE.
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 );
}