对于嵌入式调入perl的c程序,在编译的时候需要加入编译特定的编译选项,由一下命令产生:

perl -MExtUtils::Embed -e ccopts -e ldopts

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

perlembed - 在 C 程序中嵌入 perl (转)
2006-12-18 00:03

它产生这样的输出(过长的行再次折叠了):

match: Text contains the word 'quarter'.

match: Text doesn't contain the word 'eighth'.

matches: m/(wi..)/g found 2 matches...
match: will
match: with

substitute: s/[aeiou]//gi...139 substitutions made.
Now text is: Whn h s t cnvnnc str nd th bll cms t sm mnt lk 76 cnts,
Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt bck
qrtr, bt h hs n d *wht*. H fmbls thrgh hs rd sqzy chngprs nd gvs th by
thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct mnt. Th by gvs
hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s hs prz. -RCHH

substitute: s/Perl/C...No substitution made.

在 C 程序中填充 Perl 参数栈
大多数计算机教科书对于栈的解释都是重复关于放置咖啡盘的比喻(most
computer science textbooks mumble something about spring-loaded columns
of cafeteria plates):最后你放到栈中的东西就是你第一个取出的。
这是我们的要做的:C 程序放置一些参数到“Perl
栈”中,当魔术发生时闭上它的 眼睛,然后从栈上取出结果——Perl
函数的返回值(That'll do for our purposes: your C program will push some
arguments onto "the Perl stack", shut its eyes while some magic happens,
and then pop the results--the return value of your Perl subroutine--off
the stack.)

首先,你要知道怎样在 C 类型和 Perl 类型之间转换,使用 newSViv()、
sv_setnv、newAV() 以及其它它们的朋友。它们在 perlguts 和 perlapi
中有说明。

然后你要知道如何操纵 Perl 参数栈。在 perlcall 中有说明。

一旦你明白这些,在 C 中嵌入 Perl 是很简单的。

因为 C 没有内建的函数进行整数的指数运算,让我们用 Perl 的 ** 运算符实
现它(这比它听上去没用得多,因为 Perl 用 C *pow()* 函数实现 **)。首
先在 *power.pl* 中创建一个简短的指数函数:

sub expo {
my ($a, $b) = @_;
return $a ** $b;
}

现在我创建一个 C 程序 *power.c*,通过 *PerlPower()* (包含所有必须的
perlguts)将两个参数放到*expo()* 并取出返回值。深吸一口气:

#include 
#include

static PerlInterpreter *my_perl;

static void
PerlPower(int a, int b)
{
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* …is a temporary variable. */
PUSHMARK(SP); /* remember the stack pointer */
XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */
XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */
PUTBACK; /* make local stack pointer global */
call_pv(”expo”, G_SCALAR); /* call the function */
SPAGAIN; /* refresh stack pointer */
/* pop the return value from stack */
printf (”%d to the %dth power is %d./n”, a, b, POPi);
PUTBACK;
FREETMPS; /* free that return value */
LEAVE; /* …and the XPUSHed “mortal” args.*/
}

int main (int argc, char **argv, char **env)
{
char *my_argv[] = { “”, “power.pl” };

PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct( my_perl );

perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_run(my_perl);

PerlPower(3, 4); /*** Compute 3 ** 4 ***/

perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
}

编译并运行:

% cc -o power power.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

% power
3 to the 4th power is 81.

保持一个持久的解释器
当开发一个交互而且(或者)可能是持久运行的应用程序,不要多次分配构建新
的解释器,保持一个持久的解释器是一个好主意。最主要的原因是速度:因为
Perl 只要导入到内存中一次。

尽管这样,当使用一个持久的解释器时要特别小心名字空间和变量作用域。在前
面的例子中,我们在默认的包 “main” 中使用全局变量。我们很清楚地知道代
码是怎样运行的,并且假定我们能够避免变量冲突和符号表的增长。

假定你的应用程序是一个服务器,它偶尔运行一些文件中的 Perl 代码。你的服
务器是不知道要运行什么代码的。这很危险。

如果文件用 “perl_parse()” 引入的,编译成一个新创建的解释器,然后接着 用
“perl_destruct()” 作一次清理,这样就可以屏蔽了大多数的名字空间的问 题。

一个避免名字空间冲突的方法是将文件名转换成一个唯一的包名,然后用 “eval”
in perlfunc 将这段代码编译到这个包中。在下面的例子中,每个文件只
编译一次。或者这个应用程序在一个文件中的符号表不再需要时可能会清除这个
符号表。使用 “call_argv” in perlapi,我们调用在 “persistent.pl” 文件中
的 “Embed::Persistent::eval_file”,传递一个文件名以及一个清除或者缓冲
的标签作为参数。

注意到对于每个使用的文件,这个进程都要不断增长。另外,可能有 “AUTOLOAD”
函数或者其它条件导致 Perl 符号表的增长。你可能想加入一些逻
辑判断来跟踪进程的大小,或者在一定次数的请求之后重新启动一次,这样来保证
内 存的消耗是保证最小的。你可能还会在可能的时候用 “my” in perlfunc
限定变量的范围。

package Embed::Persistent;
#persistent.pl

use strict;
our %Cache;
use Symbol qw(delete_package);

sub valid_package_name {
my($string) = @_;
$string =~ s/([^A-Za-z0-9//])/sprintf(”_%2x”,unpack(”C”,$1))/eg;
# second pass only for words starting with a digit
$string =~ s|/(/d)|sprintf(”/_%2x”,unpack(”C”,$1))|eg;

# Dress it up as a real package name
$string =~ s|/|::|g;
return “Embed” . $string;
}

sub eval_file {
my($filename, $delete) = @_;
my $package = valid_package_name($filename);
my $mtime = -M $filename;
if(defined $Cache{$package}{mtime}
&&
$Cache{$package}{mtime} <= $mtime)
{
# we have compiled this subroutine already,
# it has not been updated on disk, nothing left to do
print STDERR "already compiled $package->handler/n”;
}
else {
local *FH;
open FH, $filename or die “open ‘$filename’ $!”;
local($/) = undef;
my $sub = ;
close FH;

#wrap the code into a subroutine inside our unique package
my $eval = qq{package $package; sub handler { $sub; }};
{
# hide our variables within this block
my($filename,$mtime,$package,$sub);
eval $eval;
}
die $@ if $@;

#cache it unless we’re cleaning out each time
$Cache{$package}{mtime} = $mtime unless $delete;
}

eval {$package->handler;};
die $@ if $@;

delete_package($package) if $delete;

#take a look if you want
#print Devel::Symdump->rnew($package)->as_string, $/;
}

1;

__END__

/* persistent.c */
#include 
#include

/* 1 = clean out filename’s symbol table after each request, 0 = don’t */
#ifndef DO_CLEAN
#define DO_CLEAN 0
#endif

#define BUFFER_SIZE 1024

static PerlInterpreter *my_perl = NULL;

int
main(int argc, char **argv, char **env)
{
char *embedding[] = { “”, “persistent.pl” };
char *args[] = { “”, DO_CLEAN, NULL };
char filename[BUFFER_SIZE];
int exitstatus = 0;
STRLEN n_a;

PERL_SYS_INIT3(&argc,&argv,&env);
if((my_perl = perl_alloc()) == NULL) {
fprintf(stderr, “no memory!”);
exit(1);
}
perl_construct(my_perl);

exitstatus = perl_parse(my_perl, NULL, 2, embedding, NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
if(!exitstatus) {
exitstatus = perl_run(my_perl);

while(printf(”Enter file name: “) &&
fgets(filename, BUFFER_SIZE, stdin)) {

filename[strlen(filename)-1] = ‘/0′; /* strip /n */
/* call the subroutine, passing it the filename as an argument */
args[0] = filename;
call_argv(”Embed::Persistent::eval_file”,
G_DISCARD | G_EVAL, args);

/* check $@ */
if(SvTRUE(ERRSV))
fprintf(stderr, “eval error: %s/n”, SvPV(ERRSV,n_a));
}
}

PL_perl_destruct_level = 0;
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
exit(exitstatus);
}

Now compile:

% cc -o persistent persistent.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

Here’s an example script file:

#test.pl
my $string = “hello”;
foo($string);

sub foo {
print “foo says: @_/n”;
}

Now run:

% persistent
Enter file name: test.pl
foo says: hello
Enter file name: test.pl
already compiled Embed::test_2epl->handler
foo says: hello
Enter file name: ^C

执行 END 块
传统的 END 块在 perl_run 的结束时执行了。对于不调用 perl_run 的应用程
序这会有一些问题。从 perl 5.7.2 开始,你可以指定 “PL_exit_flags |=
PERL_EXIT_DESTRUCT_END” 来获得新特性。这也可以在 perl_parse 失败之后调
用 END 块,”perl_destruct” 将返回退出值。

保持多个解释器的实例
一些罕见的应用程序在一次对话中需要创建多个解释器。可能要偶然释放解释器
对应的资源。

这个程序要确保要在下一个解释器就做这些事。默认情况下,当 perl 不用任何
选项构建时,全局变量 “PL_perl_destruct_level” 设置为 0。因为在一个程
序生存期中只创建一个解释器是不需要进行额外的清理。

将 “PL_perl_destruct_level” 设置为 1 可以使所有的都清除了:

while(1) {

/* reset global variables here with PL_perl_destruct_level = 1 */
PL_perl_destruct_level = 1;
perl_construct(my_perl);

/* clean and reset _everything_ during perl_destruct */
PL_perl_destruct_level = 1;
perl_destruct(my_perl);
perl_free(my_perl);

/* let’s go do it again! */
}

当 *perl_destruct()* 调用时,这个解释器的语法解析树和符号表就被清除,
全局变量也被重新设置。因为 perl_construct 会将 “PL_perl_destruct_level”
重新设置为 0,所以要再一次设置 “PL_perl_destruct_level”。

现在假定我们同时有多个解释器运行。这是可以做到的,但是只有在你创建 perl
时使用配置选项 “-Dusemultiplicity” 或者 “-Dusethreads
-Duseithreads”。缺省情况下,打开这些配置选项中的一个就把这个
per-interpreter 全局变量 “PL_perl_destruct_level” 设置为 1。所以清理
是自动的,并且解释器变量变正确的初始化。即使你不用同时运行多个解释器,
而是要像前面的例子那样顺序运行,但还是建议你用 “-Dusemultiplicity”
选项来编译
perl。否则一些解释器的变量在连续运行过程中不会正确的初始化,你
的运行程序可能会崩溃。

如果你打算在不同线程中并发运行多个解释器时,使用 “-Dusethreads
-Duseithreads” 而不是”-Dusemultiplicity” 可能更合适。因为这可以对解释
器支持链接到系统的线程库。

让我们来试一下:

#include #include

/* we’re going to embed two interpreters */
/* we’re going to embed two interpreters */

#define SAY_HELLO “-e”, “print qq(Hi, I’m $^X/n)”

int main(int argc, char **argv, char **env)
{
PerlInterpreter *one_perl, *two_perl;
char *one_args[] = { “one_perl”, SAY_HELLO };
char *two_args[] = { “two_perl”, SAY_HELLO };

PERL_SYS_INIT3(&argc,&argv,&env);
one_perl = perl_alloc();
two_perl = perl_alloc();

PERL_SET_CONTEXT(one_perl);
perl_construct(one_perl);
PERL_SET_CONTEXT(two_perl);
perl_construct(two_perl);

PERL_SET_CONTEXT(one_perl);
perl_parse(one_perl, NULL, 3, one_args, (char **)NULL);
PERL_SET_CONTEXT(two_perl);
perl_parse(two_perl, NULL, 3, two_args, (char **)NULL);

PERL_SET_CONTEXT(one_perl);
perl_run(one_perl);
PERL_SET_CONTEXT(two_perl);
perl_run(two_perl);

PERL_SET_CONTEXT(one_perl);
perl_destruct(one_perl);
PERL_SET_CONTEXT(two_perl);
perl_destruct(two_perl);

PERL_SET_CONTEXT(one_perl);
perl_free(one_perl);
PERL_SET_CONTEXT(two_perl);
perl_free(two_perl);
PERL_SYS_TERM();
}

注意 PERL_SET_CONTEXT() 的调用。这对于全局状态的初始化中必须的( These
are necessary to initialize the global state that tracks which
interpreter is the “current” one on the particular process or thread
that may be running it.)如果你有多个解释器并且同时对这些解释器交叉调 用
perl API,就应该总是使用它。

当 “interp” 在一个不是创建它的线程(使用 perl_alloc() 或者更深奥 的
perl_clone())使用时,也应该调用 PERL_SET_CONTEXT(interp)。

像通常那样编译:

% cc -o multiplicity multiplicity.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

赶快运行吧:

% multiplicity
Hi, I’m one_perl
Hi, I’m two_perl

在你的 C 程序中使用 Perl 模块,这些模块本身也使用 C 库
如果你在使用上面的例子中试图嵌入一个脚本,这个脚本调用一个使用 C 或者
C++ 库的 Perl 模块(例如 *Socket*),可能会发生:

Can’t load module Socket, dynamic loading not available in this perl.
(You may need to build a new perl executable which either supports
dynamic loading or has the Socket module statically linked into it.)

出什么错了?

你的解释器不知道怎样与这些扩展交流。一个小小的粘合代码将会起到作用。直
到现在你还是用 NULL 作为第二个参数调用 *perl_parse()*。

perl_parse(my_perl, NULL, argc, my_argv, NULL);

这是使用粘合代码的地方,它在 Perl 和链接的 C/C++ 函数创建起始的连接。
让我们看看在 *perlmain.c* 中的一段看看 Perl 是怎样做的:

static void xs_init (pTHX);

EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void boot_Socket (pTHX_ CV* cv);

EXTERN_C void
xs_init(pTHX)
{
char *file = __FILE__;
/* DynaLoader is a special case */
newXS(”DynaLoader::boot_DynaLoader”, boot_DynaLoader, file);
newXS(”Socket::bootstrap”, boot_Socket, file);
}

对于每个要链接到你的 Perl 可执行程序的扩展(由你电脑的初始化配置决定或
者当加入一个新的扩展),创建一个 Perl 函数整合扩展中的函数。通常这个函
数叫 *Module::boostrap()*,当你使用 *use Module* 就调用了这个函数。 In
turn, this hooks into an XSUB, *boot_Module*, which creates a Perl
counterpart for each of the extension’s XSUBs. Don’t worry about this
part; leave that to the *xsubpp* and extension authors. If your
extension is dynamically loaded, DynaLoader creates
*Module::bootstrap()* for you on the fly. In fact, if you have a working
DynaLoader then there is rarely any need to link in any other extensions
statically.

一旦你有这段代码,把它加到 *perl_parse()* 的第二个参数中:

perl_parse(my_perl, xs_init, argc, my_argv, NULL);

然后编译:

% cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

% interp
use Socket;
use SomeDynamicallyLoadedModule;

print “Now I can use extensions!/n”‘

ExtUtils::Embed 也能自动写 *xs_init* 粘合代码:

% perl -MExtUtils::Embed -e xsinit — -o perlxsi.c
% cc -c perlxsi.c `perl -MExtUtils::Embed -e ccopts`
% cc -c interp.c `perl -MExtUtils::Embed -e ccopts`
% cc -o interp perlxsi.o interp.o `perl -MExtUtils::Embed -e ldopts`

详细内容参考 perlxs、perlguts 和 perlapi。

在 Win32 嵌入 Perl
一般,这里显示的所有代码在 Windows 下不用任何修改就能工作。

尽管这样,这里有一些命令行例子的警告。对于初学者,在 Win32 本身的命令
行中是不能使用反引号的。在 CPAN 的 ExtUtils::Embed 中有一个称为 genmake
脚本。这可以从单个的 C 源文件中创建一个简单的 makefile。可 以这样使用:

C:/ExtUtils-Embed/eg> perl genmake interp.c
C:/ExtUtils-Embed/eg> nmake
C:/ExtUtils-Embed/eg> interp -e “print qq{I’m embedded in Win32!/n}”

你可能想在 Microsoft Developer Studio 中使用更稳健的环境( You may wish
to use a more robust environment such as the Microsoft Developer
Studio.)。在这种情况下中,用这个来产生 perlxsi.c:

perl -MExtUtils::Embed -e xsinit

创建一个新的工程,然后 Insert -> Files 到工程中:perlxsi.c,perl.lib,
和你自己的源文件,例如 interp.c。一般你可以在 C:/perl/lib/CORE 中找 到
perl.lib。如果没有的话,你可以用 “perl -V:archlib” 中找到 CORE
目录。studio 还要知道在哪里找到 Perl 的 include 文件。这个路径可以通过
Tools -> Options -> Directories 菜单来加入。最后,选择 Build -> Build
interp.exe,这样就好了。

隐藏 Perl_
在编译标签中加入 -DPERL_NO_SHORT_NAMES,你就可以隐藏 Perl 公共接口的简短
形式。这意味着你不能这样写:

warn(”%d bottles of beer on the wall”, bottlecount);

你必须写明确完全的形式:

Perl_warn(aTHX_ “%d bottles of beer on the wall”, bottlecount);

(参考 “Background and PERL_IMPLICIT_CONTEXT for the explanation of the
“aTHX_”.” in perlguts)隐藏简短的形式对于避免和其它软件包的冲突(C
预处理 或者其它)。(Perl 用简短名字定义了 2400
API,所以很有可能发生冲突。)

MORAL
有时可以在 C 中写出 *运行更快的代码(write faster
code)*,但是你总是可以在 Perl 中*更快地写出代码(write code
faster)*。因为你可以相互使用对方,只 要你需要可以结合起来。

AUTHOR
Jon Orwant and Doug MacEachern
, with small contributions from Tim Bunce, Tom
Christiansen, Guy Decoux, Hallvard Furuseth, Dov Grobgeld, and Ilya
Zakharevich.

Doug MacEachern has an article on embedding in Volume 1, Issue 4 of The
Perl Journal ( http://www.tpj.com/ ). Doug is also the developer of the
most widely-used Perl embedding: the mod_perl system (perl.apache.org),
which embeds Perl in the Apache web server. Oracle, Binary Evolution,
ActiveState, and Ben Sugars’s nsapi_perl have used this model for
Oracle, Netscape and Internet Information Server Perl plugins.

July 22, 1998

COPYRIGHT
Copyright (C) 1995, 1996, 1997, 1998 Doug MacEachern and Jon Orwant. All
Rights Reserved.

Permission is granted to make and distribute verbatim copies of this
documentation provided the copyright notice and this permission notice
are preserved on all copies.

Permission is granted to copy and distribute modified versions of this
documentation under the conditions for verbatim copying, provided also
that they are marked clearly as modified versions, that the authors’
names and title are unchanged (though subtitles and additional authors’
names may be added), and that the entire resulting derived work is
distributed under the terms of a permission notice identical to this
one.

Permission is granted to copy and distribute translations of this
documentation into another language, under the above conditions for
modified versions.

TRANSLATORS
YE Wenbin

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

VC中调用PERL子程序(转)

因需要,要在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";
}
附加:
1VC中嵌入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与c相互调用相关推荐

  1. python模块--如何相互调用自己写的模块

    一.模块相互调用同级目录调用时的两种方法 1 import module 2 print(module.add(3,8)) 3 4 from module import add 5 print(add ...

  2. 转载 iOS js oc相互调用(JavaScriptCore) --iOS调用js

    iOS js oc相互调用(JavaScriptCore) 从iOS7开始 苹果公布了JavaScriptCore.framework 它使得JS与OC的交互更加方便了. 下面我们就简单了解一下这个框 ...

  3. python和c++的相互调用教程

    日常工作中会遇到需要python与cpp代码之间的相互调用,工作的应用复杂,都是取决于代码的多少,但是总的方法不变,这里用两个简单例子说明下,有兴趣的筒子可以探讨下~~ 我的测试环境:ubuntu16 ...

  4. Objective-C学习笔记(十九)——对象方法和类方法的相互调用

    事实上在OC的对象方法(减号方法)和类方法(加号方法)并非相互独立的,它们也能够发生千丝万缕的关系,今天我们来研究下它们两者相互调用的问题.该样例还是以People类为基础. (一)对象方法调用类方法 ...

  5. 关于cocos2d-x 和安卓之间的相互调用

    最近在研究cocos2d游戏移植安卓需要调用很多方法,所以在研究之中写下它们之间相互调用 首先,cocos2d调用安卓 在一个.h文件中添加头文件 #include <jni.h> #in ...

  6. iOS架构-多工程联编及framework之间的相互调用(19)

    对于大公司,大工程来说,业务线很多,也时刻在变,功能模块要求能随时下线,或者业务不再需要了,就需要从主工程中移除相关工程或者库.以减小包的大小.多工程联编是一种多业务合作的一种方法. 有篇文章写的很详 ...

  7. Python实例浅谈之三Python与C/C++相互调用

    参考:http://blog.csdn.net/taiyang1987912/article/details/44779719 Python实例浅谈之三Python与C/C++相互调用 二.Pytho ...

  8. C#代码与javaScript函数的相互调用

    C#代码与javaScript函数的相互调用 问: 1.如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问JavaScript的已有变量? 4 ...

  9. python和c学习-学习 Python与C相互调用

    缘由 稀里糊涂的,用 Python 或用 C++ Qt都能写点小程序出来.然后对Python + Qt开始有点兴趣:想学PyQt4,想了解PythonQt,也期待PySide的Windows版本.但总 ...

最新文章

  1. 华为精益敏捷专家:DevOps转型中的那些坑
  2. JS(DOM对象 表单验证与正则表达)
  3. 一个页面中多个window.onload = function(){}冲突问题解决思路
  4. Serious Python
  5. 基于PredictionIO的推荐引擎打造,及大规模多标签分类探索
  6. Machine Learning week 5 quiz: programming assignment-Multi-Neural Network Learning
  7. opencv 车辆识别_丽水专业人脸自动识别系统网
  8. linux下c语言抓包库libpcap
  9. html开发日记-form button
  10. SpringRMI解析2-RmiServiceExporter逻辑脉络
  11. 28. (附加)八皇后问题(C++版本)
  12. 私有云搭建使用docker搭建
  13. java游戏主角叶开,逸之老板的天机城与叶开大神女魃墓,决赛场上谁更抢眼?...
  14. 依靠双工福禄克测试仪进行MPO电缆认证
  15. python PIL增强或降低图像对比度
  16. Visual Studio 2017,C++MFC免注册调用大漠插件图文教程,详细版
  17. CSS的引入方式:行内样式表(行内式)、内部样式表(嵌入式)、外部样式表(链接式)
  18. 【Java】List集合去重的方式
  19. Dictionary Learning详解(附带K-SVD算法)
  20. 2016-12-07 体力王哈鲁与自行车

热门文章

  1. 微信小程序 — 保存文件到本地
  2. 洛谷-P3392 涂国旗
  3. tcpdump 侦测网络端口数据
  4. 中兴通讯某产品大规模敏捷转型实践
  5. 用VBA生成PDF Adobe Acrobat and VBA – An Introduction
  6. 计算机重启无法关机,电脑无法关机或重启是为什么?
  7. 在内核中C语言实现htons()函数
  8. 利用WSUS搭建补丁升级服务器
  9. 大连软件知名公司最新职位
  10. ANativeWindow