📄 ch27.htm
字号:
file (Listing 27.3) holds the C routines that contain all the
C code for the extension, and the <TT><FONT FACE="Courier">Finance.pm</FONT></TT>
file (Listing 27.2) contains routines that tell Perl how to load
this extension and what functions are exported.
<H3><A NAME="Step3CreateaMakefile"><B>Step 3: Create a </B><TT><B><FONT SIZE=4 FACE="Courier">Makefile</FONT></B></TT></A>
</H3>
<P>
In Step 3, you have to generate a <TT><FONT FACE="Courier">makefile</FONT></TT>.
Generating and invoking the <TT><FONT FACE="Courier">make</FONT></TT>
command <TT><FONT FACE="Courier">makefile</FONT></TT> will create
a working version of the library <TT><FONT FACE="Courier">Finance.so</FONT></TT>
in the <TT><FONT FACE="Courier">../../lib/ext/Finance</FONT></TT>
directory. After testing, you can move the finished versions of
these files to the <TT><FONT FACE="Courier">/usr/lib</FONT></TT>
or <TT><FONT FACE="Courier">/usr/local/lib</FONT></TT> tree. In
all further testing in this section, you must point the <TT><FONT FACE="Courier">@Inc</FONT></TT>
array to the <TT><FONT FACE="Courier">../../lib/ext/Finance</FONT></TT>
location for this <TT><FONT FACE="Courier">finance.so</FONT></TT>
file.
<P>
You may also see a <TT><FONT FACE="Courier">blib</FONT></TT> directory
in the <TT><FONT FACE="Courier">ext/Finance</FONT></TT> directory.
The <TT><FONT FACE="Courier">man</FONT></TT> page templates for
your extensions are kept here.
<P>
Finally, the <TT><FONT FACE="Courier">Finance.xs</FONT></TT> file
where you place all your code for extension in C is shown in Listing
27.3.
<HR>
<BLOCKQUOTE>
<B>Listing 27.3. The initial </B><TT><B><FONT FACE="Courier">Finance.xs</FONT></B></TT><B>
file.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #ifdef _ _cplusplus<BR>
2 extern "C" {<BR>
3 #endif<BR>
4 #include "EXTERN.h"<BR>
5 #include "perl.h"<BR>
6 #include "XSUB.h"<BR>
7 #ifdef _ _cplusplus<BR>
8 }<BR>
9 #endif<BR>
10<BR>
11 static int<BR>
12 not_here(s)<BR>
13 char *s;<BR>
14 {<BR>
15 croak("%s not implemented
on this architecture", s);<BR>
16 return -1;<BR>
17 }<BR>
18<BR>
19 static double<BR>
20 constant(name, arg)<BR>
21 char *name;<BR>
22 int arg;<BR>
23 {<BR>
24 errno = 0;<BR>
25 switch (*name) {<BR>
26 }<BR>
27 errno = EINVAL;<BR>
28 return 0;<BR>
29<BR>
30 not_there:<BR>
31 errno = ENOENT;<BR>
32 return 0;<BR>
33 }<BR>
34<BR>
35 MODULE = Finance PACKAGE
= Finance<BR>
36<BR>
37 double<BR>
38 constant(name,arg)<BR>
39 char * name
<BR>
40 int arg</FONT></TT>
</BLOCKQUOTE>
<HR>
<H3><A NAME="Step4AddSomeCode"><B>Step 4: Add Some Code</B></A>
</H3>
<P>
Now that you have created the necessary files for your own Perl
extension, you can move to Step 3, which involves adding your
own code to the newly generated extension files. Add some simple
<TT><FONT FACE="Courier">futureValue</FONT></TT> world application
code to the <TT><FONT FACE="Courier">Finance.xs</FONT></TT> file.
Listing 27.4 shows what <TT><FONT FACE="Courier">Finance.xs</FONT></TT>
looks like with the code addition. Be sure to create this file
because you'll be using it throughout the rest of the chapter.
<HR>
<BLOCKQUOTE>
<B>Listing 27.4. After code is added to </B><TT><B><FONT FACE="Courier">Finance.xs</FONT></B></TT><B>.
<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #ifdef _ _cplusplus
<BR>
2 extern "C" {<BR>
3 #endif<BR>
4 #include "EXTERN.h"<BR>
5 #include "perl.h"<BR>
6 #include "XSUB.h"<BR>
7 #ifdef _ _cplusplus<BR>
8 }<BR>
9 #endif<BR>
10<BR>
11 static int<BR>
12 not_here(s)<BR>
13 char *s;<BR>
14 {<BR>
15 croak("%s not implemented
on this architecture", s);<BR>
16 return -1;<BR>
17 }<BR>
18<BR>
19 static double<BR>
20 constant(name, arg)<BR>
21 char *name;<BR>
22 int arg;<BR>
23 {<BR>
24 errno = 0;<BR>
25 switch (*name) {<BR>
26 }<BR>
27 errno = EINVAL;<BR>
28 return 0;<BR>
29<BR>
30 not_there:<BR>
31 errno = ENOENT;<BR>
32 return 0;<BR>
33 }<BR>
34<BR>
35 MODULE = Finance PACKAGE
= Finance<BR>
36<BR>
37 double<BR>
38 constant(name,arg)<BR>
39 char * name
<BR>
40 int arg
<BR>
41<BR>
42 double<BR>
43 futureValue(present,rate,time)<BR>
44 double present<BR>
45 double rate<BR>
46 double time<BR>
47<BR>
48 CODE:<BR>
49 double d;<BR>
50 extern double pow(double
x, double y);<BR>
51<BR>
52 d = present * pow((1.0
+ rate),time);<BR>
53 /* printf("\n
Future Value = %f \n", d); */<BR>
54 RETVAL = d;
<BR>
55<BR>
56 OUTPUT:<BR>
57 RETVAL<BR>
58<BR>
59 double<BR>
60 presentValue(future,rate,time)<BR>
61 double future<BR>
62 double rate<BR>
63 double time<BR>
64<BR>
65 CODE:<BR>
66 double d;<BR>
67 extern double pow(double
x, double y);<BR>
68<BR>
69 d = future / pow((1.0
+ rate),time);<BR>
70 /* printf("\n
Present Value = %f \n", d); */<BR>
71 RETVAL = d;
<BR>
72<BR>
73 OUTPUT:<BR>
74 RETVAL<BR>
75<BR>
76 void<BR>
77 Gordon(d,r,g)<BR>
78 double d<BR>
79 double r<BR>
80 double g<BR>
81<BR>
82 CODE:<BR>
83 /*
Return Gordon Growth Model Value of stock */<BR>
84 g = d / (r -g);<BR>
85 printf("\n g
= %f", g);<BR>
86<BR>
87 void<BR>
88 depreciateSL(p,s,n)<BR>
89 double p<BR>
90 double s<BR>
91 double n<BR>
92<BR>
93 PpcODE:<BR>
94 double sum;<BR>
95 double value[10];
<BR>
96 double dep;<BR>
97 int i;<BR>
98 int in;<BR>
99 in = (int)n;
<BR>
100 if ((n < 10) &&
(n > 0))<BR>
101 {
<BR>
102 EXTEND(sp,in);
<BR>
103 sum =
p;<BR>
104 printf("value
= %f for %d years \n", sum,in);<BR>
105 dep
= (sum - s)/ n;<BR>
106 for
(i=0; i<n; i++)<BR>
107 {
<BR>
108 sum
-= dep;<BR>
109 printf("value
= %f \n", sum);<BR>
110 value[i]
= sum;<BR>
111 PUSHs(sv_2mortal(newSViv(sum)));
<BR>
112 }
<BR>
113 }</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
A function to calculate the future value of an investment is defined
in line 43. The function to calculate the present value of money
to be received in the future from an investment is defined starting
at line 60. Both functions return one value and require three
arguments, which are defined one per each line following the function
declaration. For example, for the present value function in line
60, the three arguments must be defined in one line as
<BLOCKQUOTE>
<TT><FONT FACE="Courier">double future, rate, time;</FONT></TT>
</BLOCKQUOTE>
<P>
At line 77, I define a Gordon Growth model function for a stock.
This function only prints something and does not return any values.
At line 88, I define a straight line depreciation model function
that returns more than one value on the calling stack.<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD><B>Caution</B></TD></TR>
<TR VALIGN=TOP><TD>
<BLOCKQUOTE>
Be careful to put the type of function and the name of the function on separate lines. In other words, do not shorten the two lines into one. The return parameter and the function name must be on two lines for the XS specification. Any arguments to the
function would have be to listed one at a time on each line following the function name.</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
Next, run the command <TT><FONT FACE="Courier">perl Makefile.PL</FONT></TT>.
This creates a real makefile, which <TT><FONT FACE="Courier">make</FONT></TT>
needs. The <TT><FONT FACE="Courier">Makefile.PL</FONT></TT> checks
to see whether your Perl distribution is complete and then writes
the makefile for you.
<P>
If you get any errors at this point, you should check to see whether
your Perl distribution is complete. As a check, try running the
<TT><FONT FACE="Courier">Makefile.PL</FONT></TT> script as <TT><FONT FACE="Courier">root</FONT></TT>.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -