VC中調用PERL子程式
作者: 來源:zz 發表時間:2007-02-09 瀏覽次數: 2691 字型大小:大 中 小
因需要,要在VC中調用PERL子程式對檔案進行處理。通過看PERL說明文檔折騰了好長時間,可以運行。現與大家分享,呵呵,希望對大家有所協助^ -^
1在工程檔案中加入 perl58.dll
2. 在VC中加入標頭檔
#include <EXTERN.h>
#include <perl.h>
3.
void perl_sub(char*a)
{
int retval;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv(a, 0)));
PUTBACK;
retval=call_pv("readfile",G_ARRAY);
SPAGAIN;
for (int i = 1; i <= retval;++i)
{ int t=POPl;
printf ("Value %d = %d\n", i, t);
}
PUTBACK;
FREETMPS;
LEAVE;
}
int main(int argc, char **argv, char **env)
{
char *args[] = { " ","sub.pl" };
PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct(my_perl);
perl_parse(my_perl, NULL, argc, args,(char**)NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_sub("test.txt");
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
int i;
scanf("%d",&i);
}/////////////////////////////////////////////調用PERL結束
註:sub.pl的內容
sub readfile
{
my($s) = @_;
#my($s) ="test.txt";
open(FH,$s)||die "can't open FH;$!"; #讀取文字檔
my @readstr=<FH>;
#print @readstr;
$filename="22.bin";
open(IN,">:raw",$filename) or die "cannot open $filename !\n"; #open(IN,">>:raw",$filename)是追加寫
seek(IN,0,SEEK_SET);
foreach my $one (@readstr) #對每行進行處理
{
#chop($one);
my @words3=split(/\s+/,$one);
if ($words3[12] eq "綠燈")
{$words3[12]=0;}
if ($words3[12] eq "綠黃燈")
{$words3[12]=1;}
#print "\n";
#print @words3;
print IN pack("n16",@words3);
}
#close(IN) or die "cannot close\n";
}
附加:
1.VC中嵌入PERL片段
#include "stdafx.h"
#include <EXTERN.h>
#include <perl.h>
static PerlInterpreter *my_perl;
main (int argc, char **argv, char **env)
{
STRLEN n_a;
char *embedding[] = { "", "-e", "0" };
PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct( my_perl );
perl_parse(my_perl, NULL, 3, embedding, NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_run(my_perl);
// eval_pv(" $a = 3; $a **= 2", TRUE);
eval_pv(" $a = 3; $a **= 2", TRUE);
printf("a = %d\n", SvIV(get_sv("a", FALSE)));
eval_pv("$a = 3.14; $a **= 2", TRUE);
printf("a = %f\n", SvNV(get_sv("a", FALSE)));
eval_pv(" {$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a);}", TRUE);
printf("a = %s\n", SvPV(get_sv("a", FALSE), n_a));
eval_pv("print 'Please enter first number:';$number1 = <STDIN>;chomp $number1;$number2 = <STDIN>;chomp $number2;$sum = $number1 + $number2;", TRUE);
printf("sum = %f\n", SvNV(get_sv("sum", FALSE)));
eval_pv("print 'hello'", TRUE);
// eval_pv("my $today = new Date;$today->setDate( 7, 14, 2000 );print( $today->month() );print( '\n' );$today->print();print( '\n' );", TRUE);
//eval_pv("use strict; $a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a);", TRUE);
//printf("a = %s\n", SvPV(get_sv("a", FALSE), n_a));
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
int i;
scanf("%d",&i);
}
2.在PERL中嵌入C
use Inline C;
{
# $a=5;
#$b=19;
@c=(9,19);
print "begin\n";
print "9 + 19 = ", add(@c,"STRING"), "\n";
print "9 - 16 = ", subtract(9, 16), "\n";
print "end\n";
}
__END__
__C__
int add(int a,int b,char* z) {
int words[2]={0,0};
words[0]=a;
words[1]=b;
printf("%s",z);
return words[0]+words[1];
}
int subtract(int x, int y) {
return x - y;
}
今日,改寫一些perl產生順序遞增數的代碼。為滿足測試,需要不斷運行以產生新的一百萬個隨機數。由於起始數不同,每次都需要在代碼裡的修改再運行(或敲命令的傳遞)。若只是我使用,也不會覺得太麻煩。但,隊友使用起來就不太方便。還是用VC做個介面,在C/C++代碼裡調用perl指令碼,做成笨蛋按鈕式的,呵呵。。。
說真的,還真不知如何用C/C++調用perl呢?(當然這裡的C/C++,俺是說用VS環境裡的)。
網上搜尋一下,CSDN裡花3個積分下了一份簡便的說明文檔(作者是誰忘了,別怪我)。操作步驟如下:
1.VS裡的工程設定:
工具->選項->項目和解決方案->VC++目錄,在“顯示以下內容的目錄(S):”下拉框中選擇“包括檔案”, 添加*\bin, *\lib\core,*表示perl的安裝路徑。
工具->選項->項目和解決方案->VC++目錄,在“顯示以下內容的目錄(S):”下拉框中選擇“庫檔案”,添加*\lib\core, *表示perl的安裝路徑。
把perl58.lib加入到工程中,項目->“項目”屬性->配置屬性->連結器->命令列,在附加選項裡加上perl56.lib(因為俺用的perl版本是5.6的)
2.在項目的代碼裡添加標頭檔
#include"EXTERN.h" //引用外部的標頭檔
#include"perl.h" //perl標頭檔
3. 項目程式碼
int_tmain(int argc, _TCHAR* argv[])
{
// char *embedding[] ={"","C:\\data.pl","E:\\dumptobin"};//perl指令碼和參數,第一個為空白,沒有空格,
//第二個為指令檔,第三個為指令碼的輸入參數
char*embedding[] = {"","C:\\perl2\\CreateNumber.pl",""};//俺的perl指令碼的真實路徑,沒有輸入參數
static PerlInterpreter*my_perl;//定義一個perl解譯器
my_perl =perl_alloc();//為解譯器分配資源
perl_construct( my_perl);//建立一個解譯器
perl_parse(my_perl, NULL, 3, embedding,NULL);//perl解析
//perl_parse函數原型是:
//PERL_CALLCONV intperl_parse(PerlInterpreter* interp, XSINIT_t xsinit, int argc,char** argv, char** env)
perl_run(my_perl);//運行
// int str =SvIV(perl_get_sv("lastValue",FALSE));//把perl指令碼中的變數lastValue傳給C中的變數str,無效的語句
// printf("傳回值為%d.\n", str);
perl_destruct(my_perl);//析構解譯器
perl_free(my_perl);//釋放解譯器
return 0;
}
大體上就這些了。其它的用VS做介面框,各人需要自己去弄。(當然你得先安裝了Perl)。
當然,這個仍是一個VC程式硬綁定一個perl指令碼,若要實現程式介面(上面暫是控制台)和運行時刻選擇perl指令碼,嘿嘿,那就通過讀一個設定檔以傳遞指令碼名稱吧。
參考頁面:(在C 程式中嵌入 perl)
http://bbs.chinaunix.net/viewthread.php?tid=770248###