[21902] in Perl-Users-Digest
Perl-Users Digest, Issue: 4106 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Nov 12 18:07:09 2002
Date: Tue, 12 Nov 2002 15:05:16 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 12 Nov 2002 Volume: 10 Number: 4106
Today's topics:
Re: A vision for Parrot (Phil Tomson)
Re: A vision for Parrot <mikkelfj-anti-spam@bigfoot.com>
Re: A vision for Parrot <goldbb2@earthlink.net>
Re: A vision for Parrot <slaven.rezic@berlin.de>
Re: A vision for Parrot <goldbb2@earthlink.net>
Re: A vision for Parrot <mikkelfj-anti-spam@bigfoot.com>
Building Perl on Windows as Static Library (as opposed (Anthony Shaffer Lyris)
DBI, mysql, how do I get the results into an array with <spam@digitaltension.com>
Re: Global file search function? <tassilo.parseval@post.rwth-aachen.de>
Re: Global file search function? (Bryan Castillo)
Re: Global file search function? <tk@WINDOZEdigiserv.net>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 12 Nov 2002 19:13:28 GMT
From: ptkwt@shell1.aracnet.com (Phil Tomson)
Subject: Re: A vision for Parrot
Message-Id: <aqrjso012t9@enews3.newsguy.com>
In article <LRaA9.1325$J55.292310@newsfep2-win.server.ntli.net>,
Neil Madden <nem00u@cs.nott.ac.uk> wrote:
>Donal K. Fellows wrote:
>
><snip interesting discussion, which mostly goes over my head :>
>
>>
>> BTW, how does Parrot handle calls to foreign code? The docs I've seen are on
>> the hazy side, and integration with existing C, C++ and FORTRAN monoliths is
>> (alas) all too important in particularly commercial development.
>>
>
>On this particular point; has anyone thought of writing a unified C-API
>for Tcl,
>Perl, Python, Ruby, (Java) etc? What I mean by this is that each of these
>languages can be extended in C, and quite often are. Also, whenever I see
>interesting new C/C++ libraries implemented, I also tend to see seperate
>language bindings for each of these languages. This seems like a massive
>duplication of effort. Would it be possible to abstract over the C API's of
>these languages to a common core of functionality which all share (e.g. getting
>an interpreter handle, registering a command, setting a variable etc)? I have
>only dealt with Tcl's C interface, so this may be too difficult, but it seems
>like it would be a huge step forward.
>In terms of problems implementing this, I can see several problems:
>1. Method of calling C-coded procedures. In Tcl, arguments are passed to C
>procedures as Tcl_Obj's. Obviously this would be different for Perl or Python.
>Is it possible to come up with an API which can convert to the appropriate
>object type, or to some intermediate type?
>2. Accessing functions which are not present in all languages. I'm sure there
>are API's in Tcl which only make sense with respect to Tcl, and probably the
>same in the other languages. So, how would one create a general API which
>allows you to call language specific APIs? In the same way one handles platform
>specific APIs?
>3. Versioning. Which language versions are compatible with which
>abstract API? I
>can see this one becoming insane over time. However, there are people with much
>more experience with these issues than me, so there might be a way.
>4... probably more, this is all coming of the top of my head.
>
>Hmm.. the more I think about this, the more problems it seems to present. I'd
>love to be able to write an extension, and have it instantly work with x
>different langauges. Also, I'd love to be able to use Python and Perl
>extensions from Tcl, without loading seperate interpreters and all that. Am I
>dreaming of an impossible Utopia?
>
Check out swig: http://www.swig.org
it's the closest thing to a cross-language unified C/C++ API. You can
create an interface file that (little or no changes depending on the
library you want to wrap) can be used to create a wrapper for each of the
major languages - Ruby, Perl, Python, TCL and (to some extent) Java are
supported. So basically, by changing a commandline option you can create
a wrapper for a different langauge, for example say there is an existing
C++ class library you want to access called FooLib. All of the
API/classes are defined in FooLib.h. You need to create an interface file
for FooLib called FooLib.i:
//FooLib.i
%module FooLib
%{
#include FooLib.h
%}
#include FooLib.h
//end of FooLib.i
Now to create the Ruby wrapper:
$ swig -ruby -c++ FooLib.i
To create the Python wrapper:
$ swig -python -c++ FooLib.i
...etc.
(Ok, depending on the library being wrapped and the target language there
may be some language specific changes that need to be applied to the .i
file, but I believe there are language specific #ifdef's , like #ifdef
RUBY, that can be put in the .i file so the same .i file can be used to
target several languages)
Swig really shines when it comes to creating wrappers for existing libs.
It would be great if folks would start to use swig to create wrappers
because then they would pretty much immediately become available to all of
the major scripting languages with little or no modification.
Phil
------------------------------
Date: Tue, 12 Nov 2002 21:55:30 +0100
From: "MikkelFJ" <mikkelfj-anti-spam@bigfoot.com>
Subject: Re: A vision for Parrot
Message-Id: <3dd169f1$0$63897$edfadb0f@dread15.news.tele.dk>
"Neil Madden" <nem00u@cs.nott.ac.uk> wrote in message
news:LRaA9.1325$J55.292310@newsfep2-win.server.ntli.net...
> Hmm.. the more I think about this, the more problems it seems to present.
I'd
> love to be able to write an extension, and have it instantly work with x
> different langauges. Also, I'd love to be able to use Python and Perl
> extensions from Tcl, without loading seperate interpreters and all that.
Am I
> dreaming of an impossible Utopia?
I wrote some DLL helper logic that makes it easy to query a vtable by name
in another DLL.
The vtables can be created in whatever way, but the vtable is not assocated
with allocated memory, as is the case with COM. This makes it quite flexible
without really being limited because one could decide that the first
function should return a 'this' pointer and the second function should be
the destructor, or whatever.
In any DLL that can link statically with a piece of C, you can use this
framework to pass functions around. (Even if you can only link dynamically,
you could have a helper dll to expose vtables). I use some #define macros to
create the vtables statically (see snippet below). It's then very easy to
take arbitrary C functions and wrap them up in one or more vtables. However,
vtables need not be statically allocated (and this is significantly
different from public dll functions).
Because the vtables are looked up by name initially, you could handle
versioning like in COM: "mycomponent.vtablename.1", where
"mycomponent.vtablename" would refer to the most recent version - but it is
preferable to always specificy an exact version.
Contrary to COM this is completely cross platform as there is no OS magic
involved.
When a vtable is created, it is helpful to write a C prototype struct that
matches, because this makes things easier clientside - but it is not
required (see snippet below).
On the clientside I wrote some small wrappers to ease loading dll's
dynamically and in C++ to wrap the optional prototype. I only did this for
Windows, but the principles are essentially the same on Linux, just like
Ruby loads .so files.
The framework is generic - here is what I did to access functionality in a
OCaml parser application I wrapped up as selfcontained dll - without using
public dll functions except for init, query vtable and uninit functions: I
picked all the most relevant OCaml API logic for allocating memory on the
OCaml runtime stack and created a set of vtables approximately one for each
.h file in the API. The Ocaml OCaml functions I wrote (parse_file) I had to
dynamically call a function to locate the OCaml function address. In the dll
init logic I performed this operation and added the result to a vtable
already prepared for the purpse. The client of the dll loads the dll, calls
init and then queries relevant vtables, but in principle has no clue that it
really is OCaml the executes the logic (in principle because in praxis I
wanted to know in order to efficiently allocate memory).
The same thing could be done in Ruby, wrapping rb_... functions into vtables
and having separate vtables for calling Ruby code - this vtables would be
created dynamically or at least filled dynamically.
Any language that supports C integration and dynamic link libraries can use
this framework.
Incidentally Parrot works a lot with vtables, so there could be some overlap
here (I didn't know that at the time I wrote the framework though).
I have not put the code online, but if anyone is interested, let my know.
Below is a readme snippet, a bit technical and not the only way to use the
framework (it would be possible to map Ruby functions into dynamically
created vtables for instance).
Mikkel
<snip>
Interfaces are organized in vtable maps which are statically allocated
arrays of VtblMapEntries.
VTBL_MAP_BEGIN(<vtbl_map_name>)
VTBL_MAP_ENTRY(name, vtbl)
... more entries here ...
VTBL_MAP_END
The name <vtbl_map_name> is later used be the linker, such that the map
can be hooked into a master
map of all vtable interfaces compiled together.
The master map is located in a central compilation unit such that new
vtable maps can easily be
added to the master map without modifying the source of any of the
existing map providers.
Before entering the map into the mastermap, it must be declared - unless
the map is earlier in the same
compilation unit as the master map:
VTBL_DECLARE_MAP(<vtbl_map_name>)
... more maps declared here ...
Following the map declareations, there is a master map which is scanned
by the default lookup function:
VTBL_MASTER_MAP_BEGIN(<vtbl_master_map_name>)
VTBL_MASTER_MAP_ENTRY(<vtbl_map_name>)
... more master map entries here ...
VTBL_MASTER_MAP_END
Typically, a dynamically loaded library (dll) will have a purpose
specific mastermap using a selection
of available vtbl interface maps.
Example:
we have the following functions in a .c file. Moreover, we have the
malloc and free functions
from the std library. We want all four functions wrapped in two
interfaces: FooBar and Mem.
First we create a header file for the interfaces:
<file "examples.h">
struct
{
int (*get)(int x);
void (*set)(int x, int val);
void *(*create)(int x);
} ExamplesVectorVtbl;
struct
{
void *(*allocate)(size_t size);
void (*deallocate)(void *p);
} ExamplesMemoryVtbl;
</file>
<file "examples.c">
#include <memory.h>
#include "vtbl.h"
#include "examples.h"
void set(void *p, int x, int val) { return ((int*)p)[x] = val; };
int get(void *p, int x) { return ((int*)p)[x]; }
void *create(int x) { return calloc(x * sizeof(int)); };
ExamplesVectorVtbl { get, set, create } vector_vtbl;
/* shows that existing library functions can be packaged as well */
ExamplesMemoryVtbl { calloc, free } mem_vtbl;
VTBL_MAP_BEGIN(examples_vtbl_map)
VTBL_MAP_ENTRY("Examples.Vector", vector_vtbl)
VTBL_MAP_ENTRY("Examples.Memory", mem_vtbl)
VTBL_MAP_END
</file>
<file "master.c">
/* to get vtbl.h and the lookup function in vtbl.c */
#include "vtbl.c"
VTBL_DECLARE_MAP(examples_vtbl_map)
VTBL_MASTER_MAP_BEGIN(vtbl_master_map)
VTBL_MASTER_MAP_ENTRY(examples_vtbl_map)
VTBL_MASTER_MAP_END
void *GetNamedInterface(char *name)
{
return vtbl_master_map_lookup(vtbl_master_map, name);
}
</file>
<file "client.c">
#include "examples.h"
void *GetNamedInterface(char *name);
void test()
{
/* since interfaces are static, pMem and pVec need not be
deallocated */
Examples_Memory *pMem =
(Examples_Memory*)GetNamedInterface("Examples.Memory");
Examples_Vector *pVec =
(Examples_Vector*)GetNamedInterface("Examples.Vector");
void *v1 = pMem->allocate(sizeof(int[4]));
void *v2 = pVec->create(4);
pVec->set(v1, 2, 42);
pVec->set(v2, 0, pVec->get(v1, 2));
pMem->deallocate(v1);
pMem->deallocate(v2);
}
</file>
Typically the client would have loaded a dynamically linked library and
found the address of the published
GetNamedInterface function. Once that function is avaible, it is easy to
access all the remaining functions
via the named interfaces.
</snip>
------------------------------
Date: Tue, 12 Nov 2002 16:13:40 -0500
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: A vision for Parrot
Message-Id: <3DD16F04.517E6720@earthlink.net>
Donal K. Fellows wrote:
>
> Benjamin Goldberg wrote:
> > Considering that Jcl and Jython exist, it seems like a reasonable
> > goal
>
> (JCL is something else. I'd rather not remember it thankyouverymuch.)
Erm... that's the old IBM Job Control Language? You mean this one?
http://www.tuxedo.org/~esr/jargon/html/entry/JCL.html
Bleh, forget I mentioned it. :) Twas a horrible typo :)
> > would be to make an interpreter which turns Java's .class files into
> > Parrot .pasm files. Once that tool exists, one could simply
> > translate Jcl and Jython into parrot... there would be no need to
> > re-implement them.
> >
> > And one day, in the distant future, there will be a Perl6
> > decompiler, which will turn Parrot bytecode into Perl6. Then we'll
> > be able to convert the translated Jython and Jcl into Perl6 :)
>
> $10 says that only ever happens with a performance hit. The problem
> is that not all bytecodes are created equal. (And Jacl is an
> implementation of Tcl in Java more in the way that the usual form of
> Tcl is an implementation of the language in C.
So Jacl still converts Tcl into, well, Tcl bytecodes, even though it's
doing so in Java? Blech.
Hmm, is there a way of making tcl dump the tcl-bytecodes to a file?
If so, one could probably make an attempt to translate those bytecodes
into parrot. (And ignore Jacl).
> The fact that Java uses bytecodes is pretty much just a distraction
> here. We also have another way of integrating Tcl with Java that
> keeps Tcl
> implemented in C, but which integrates almost identically with the Java
> language.)
>
> > > This sort of thing tends to make me suspicious that this is little
> > > more than a pipe-dream, well, at least as far as Tcl's concerned.
> > > (I don't know the other languages nearly well enough to comment
> > > in a useful way.)
> [...]
> > Assuming you thouroughly understand Tcl's bytecodes, why not take a
> > look at Parrot, and see whether the set of bytecodes that parrot
> > supports is sufficient to do everything that Tcl's bytecodes do?
>
> I know a bit about Tcl bytecodes, and a key factor about them is that
> they are very tightly targetted towards implementing Tcl.
>
> Hmm. A quick scan through the documentation doesn't really raise my
> hopes. Or even leave me with a deep enough understanding of what's
> going on; is there any deeper description than
> http://www.parrotcode.org/docs/parrot_assembly.pod.html
> about? (OK, Tcl's bytecodes need documentation too, but I've already
> gone to the effort to understand those as part of my maintenance and
> development duties. I've just not got enough hours in the day.)
> Unfortunately, the bits that I'm most interested in seem to be the
> bits with least info (isn't that always the way with complex software
> systems?)
>
> First impressions: what is meant by "string" anyway? Character
> sequence? Byte sequence? UTF-8 sequence? ISO 8859-1 sequence? [FX:
> Reads docs] Oh, they carry about what their encoding is with them?
> That must make working with them fun. How does it handle things like
> the blecherous monstrosities[*] used for system encodings in the Far
> East?
Having read http://www.parrotcode.org/docs/strings.pod.html only just
now myself, it's possible I could be wrong on this, but...
Each string's encoding can be one of native, utf8, utf16, utf32, or
foreign. So those "blecherous monstrosities" will either be converted
to one of the utf formats, or else have their own string vtable.
For now, they will probably be converted... the strings.pod.html says
this at the bottom:
Foreign Encodings
Fill this in later; if anyone wants to implement
new encodings at this stage they must be mad."
> On a quite separate point, is there a strncmp() equivalent? That
> would make implementing Tcl much easier...
You mean, for testing the first n characters of two strings for
equality? There isn't that I know of, but one could always be added;
furthermore, it supposedly will be possible to make lightweight strings
which are substrings of other strings, without any copying involved.
You could make your strncmp be a wrapper around making a substring of
the first n characters of each of your two strings, and comparing those
substrings.
> More generally, Tcl would need to use PMCs throughout.
Why? (Not an objection, but I don't know much about Tcl's bytecode)
> The problem is that Tcl's value semantics (copy-on-write) do not line
> up well with that which Parrot seems to use (object-based)
Parrot will do copy-on-write.
Furthermore, Parrot may implement some strings as ropes, so that the
amount that needs to be copied will be even smaller.
> and which, IIRC from the discussions at the time when Parrot was being
> created, are closely based on those used in Perl even if not precisely
> coincident.
Perl is likely never going to implement strings as ropes. It does now
have copy-on-write, though this is a recent development.
Perl5.6+ has two internal encodings for strings -- bytes and utf8.
Parrot not only allows native, utf8, utf16, and utf32, but it also
allows any kind of user-defined encoding one might want. I doubt that
perl5 will ever do this.
> Hence we'd be unable to use ground values except as part of the
> implementation of higher-level concepts. That'll impact badly on
> performance.
>
> It's at this point that I feel a round of "Stuff it. I'll stick to
> implementing in C." coming on. I've been quietly watching Parrot for
> a while now, and I still don't think that implementing Tcl in it is
> really a winning proposition.
> I'd love someone to prove me wrong, but proof is building a Tcl
> interpreter in or on top of Parrot and running the Tcl test suite on
> it (and getting a decent proportion of the tests passing.)
Parrot does everything in two steps -- compile, then run. Most likely,
it will have a compiler which converts Tcl bytecode to Parrot bytecode.
Whether or not Parrot will ever translate from Tcl source to Parrot
bytecode is another question entirely.
Thinking a bit more, particularly about how Tcl often needs to interpret
strings at runtime, I realize that no non-trivial Tcl program can work
without having a string-to-bytecode compiler. Needless to say, this
poses a problem.
> BTW, how does Parrot handle calls to foreign code? The docs I've seen
> are on the hazy side, and integration with existing C, C++ and FORTRAN
> monoliths is (alas) all too important in particularly commercial
> development.
Although I don't know *how* it will handle foreign code, I do know that
it *will* handle foreign code, and have a better interface than Perl5's
cruddy XS extension language.
--
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]
------------------------------
Date: 12 Nov 2002 22:21:49 +0100
From: Slaven Rezic <slaven.rezic@berlin.de>
Subject: Re: A vision for Parrot
Message-Id: <87pttao55e.fsf@vran.herceg.de>
Neil Madden <nem00u@cs.nott.ac.uk> writes:
> Donal K. Fellows wrote:
>
> <snip interesting discussion, which mostly goes over my head :>
>
> >
> > BTW, how does Parrot handle calls to foreign code? The docs I've seen are on
> > the hazy side, and integration with existing C, C++ and FORTRAN monoliths is
> > (alas) all too important in particularly commercial development.
> >
>
> On this particular point; has anyone thought of writing a unified C-API for Tcl,
> Perl, Python, Ruby, (Java) etc? What I mean by this is that each of these
> languages can be extended in C, and quite often are. Also, whenever I see
> interesting new C/C++ libraries implemented, I also tend to see seperate
> language bindings for each of these languages. This seems like a massive
> duplication of effort. Would it be possible to abstract over the C API's of
> these languages to a common core of functionality which all share (e.g. getting
> an interpreter handle, registering a command, setting a variable etc)? I have
> only dealt with Tcl's C interface, so this may be too difficult, but it seems
> like it would be a huge step forward.
Look at
http://www.swig.org/
Regards,
Slaven
--
Slaven Rezic - slaven.rezic@berlin.de
Tired of using file selectors? Real programmers use the TAB key for
completion and not for jumping around. Try
http://search.cpan.org/search?mode=module&query=Tk::PathEntry
------------------------------
Date: Tue, 12 Nov 2002 16:47:59 -0500
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: A vision for Parrot
Message-Id: <3DD1770F.4FEAB063@earthlink.net>
Donal K. Fellows wrote:
>
> Benjamin Goldberg wrote:
> > The set of bytecodes which Parrot will be using has been decided,
> > and while it's not fixed in stone, it's quite unlikely to get a
> > whole other language's bytecodes added to it.
>
> OK, let's go for a more concrete question. What sequence of bytecodes
> would let me open a socket and talk to a remote host? The Parrot I/O
> operation opcodes don't mention anything about sockets and nor can I
> tell how I would invoke a piece of helper C or C++ to do the job on my
> behalf.
Just as there are "stdio", "unix", and "win32" ParrotIO layers, one
would define a "socket" layer (and maybe an "xti" layer, for the really
adventurous). Obviously, this needs a bit more C code to be added.
Once that layer is added, you could read from and write to sockets just
like you would from files.
--
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]
------------------------------
Date: Tue, 12 Nov 2002 23:26:01 +0100
From: "MikkelFJ" <mikkelfj-anti-spam@bigfoot.com>
Subject: Re: A vision for Parrot
Message-Id: <3dd17f27$0$195$edfadb0f@dread16.news.tele.dk>
Sorry for the repost at perl, I didn't release the post was crossposted (I
entered via Ruby).
"Neil Madden" <nem00u@cs.nott.ac.uk> wrote in message
news:LRaA9.1325$J55.292310@newsfep2-win.server.ntli.net...
> Hmm.. the more I think about this, the more problems it seems to present.
I'd
> love to be able to write an extension, and have it instantly work with x
> different langauges. Also, I'd love to be able to use Python and Perl
> extensions from Tcl, without loading seperate interpreters and all that.
Am I
> dreaming of an impossible Utopia?
I wrote some DLL helper logic that makes it easy to query a vtable by name
in another DLL.
The vtables can be created in whatever way, but the vtable is not assocated
with allocated memory, as is the case with COM. This makes it quite flexible
without really being limited because one could decide that the first
function should return a 'this' pointer and the second function should be
the destructor, or whatever.
In any DLL that can link statically with a piece of C, you can use this
framework to pass functions around. (Even if you can only link dynamically,
you could have a helper dll to expose vtables). I use some #define macros to
create the vtables statically (see snippet below). It's then very easy to
take arbitrary C functions and wrap them up in one or more vtables. However,
vtables need not be statically allocated (and this is significantly
different from public dll functions).
Because the vtables are looked up by name initially, you could handle
versioning like in COM: "mycomponent.vtablename.1", where
"mycomponent.vtablename" would refer to the most recent version - but it is
preferable to always specificy an exact version.
Contrary to COM this is completely cross platform as there is no OS magic
involved.
When a vtable is created, it is helpful to write a C prototype struct that
matches, because this makes things easier clientside - but it is not
required (see snippet below).
On the clientside I wrote some small wrappers to ease loading dll's
dynamically and in C++ to wrap the optional prototype. I only did this for
Windows, but the principles are essentially the same on Linux, just like
Ruby loads .so files.
The framework is generic - here is what I did to access functionality in a
OCaml parser application I wrapped up as selfcontained dll - without using
public dll functions except for init, query vtable and uninit functions: I
picked all the most relevant OCaml API logic for allocating memory on the
OCaml runtime stack and created a set of vtables approximately one for each
.h file in the API. The Ocaml OCaml functions I wrote (parse_file) I had to
dynamically call a function to locate the OCaml function address. In the dll
init logic I performed this operation and added the result to a vtable
already prepared for the purpse. The client of the dll loads the dll, calls
init and then queries relevant vtables, but in principle has no clue that it
really is OCaml the executes the logic (in principle because in praxis I
wanted to know in order to efficiently allocate memory).
The same thing could be done in Ruby, wrapping rb_... functions into vtables
and having separate vtables for calling Ruby code - this vtables would be
created dynamically or at least filled dynamically.
Any language that supports C integration and dynamic link libraries can use
this framework.
Incidentally Parrot works a lot with vtables, so there could be some overlap
here (I didn't know that at the time I wrote the framework though).
I have not put the code online, but if anyone is interested, let my know.
Below is a readme snippet, a bit technical and not the only way to use the
framework (it would be possible to map Ruby functions into dynamically
created vtables for instance).
Mikkel
<snip>
Interfaces are organized in vtable maps which are statically allocated
arrays of VtblMapEntries.
VTBL_MAP_BEGIN(<vtbl_map_name>)
VTBL_MAP_ENTRY(name, vtbl)
... more entries here ...
VTBL_MAP_END
The name <vtbl_map_name> is later used be the linker, such that the map
can be hooked into a master
map of all vtable interfaces compiled together.
The master map is located in a central compilation unit such that new
vtable maps can easily be
added to the master map without modifying the source of any of the
existing map providers.
Before entering the map into the mastermap, it must be declared - unless
the map is earlier in the same
compilation unit as the master map:
VTBL_DECLARE_MAP(<vtbl_map_name>)
... more maps declared here ...
Following the map declareations, there is a master map which is scanned
by the default lookup function:
VTBL_MASTER_MAP_BEGIN(<vtbl_master_map_name>)
VTBL_MASTER_MAP_ENTRY(<vtbl_map_name>)
... more master map entries here ...
VTBL_MASTER_MAP_END
Typically, a dynamically loaded library (dll) will have a purpose
specific mastermap using a selection
of available vtbl interface maps.
Example:
we have the following functions in a .c file. Moreover, we have the
malloc and free functions
from the std library. We want all four functions wrapped in two
interfaces: FooBar and Mem.
First we create a header file for the interfaces:
<file "examples.h">
struct
{
int (*get)(int x);
void (*set)(int x, int val);
void *(*create)(int x);
} ExamplesVectorVtbl;
struct
{
void *(*allocate)(size_t size);
void (*deallocate)(void *p);
} ExamplesMemoryVtbl;
</file>
<file "examples.c">
#include <memory.h>
#include "vtbl.h"
#include "examples.h"
void set(void *p, int x, int val) { return ((int*)p)[x] = val; };
int get(void *p, int x) { return ((int*)p)[x]; }
void *create(int x) { return calloc(x * sizeof(int)); };
ExamplesVectorVtbl { get, set, create } vector_vtbl;
/* shows that existing library functions can be packaged as well */
ExamplesMemoryVtbl { calloc, free } mem_vtbl;
VTBL_MAP_BEGIN(examples_vtbl_map)
VTBL_MAP_ENTRY("Examples.Vector", vector_vtbl)
VTBL_MAP_ENTRY("Examples.Memory", mem_vtbl)
VTBL_MAP_END
</file>
<file "master.c">
/* to get vtbl.h and the lookup function in vtbl.c */
#include "vtbl.c"
VTBL_DECLARE_MAP(examples_vtbl_map)
VTBL_MASTER_MAP_BEGIN(vtbl_master_map)
VTBL_MASTER_MAP_ENTRY(examples_vtbl_map)
VTBL_MASTER_MAP_END
void *GetNamedInterface(char *name)
{
return vtbl_master_map_lookup(vtbl_master_map, name);
}
</file>
<file "client.c">
#include "examples.h"
void *GetNamedInterface(char *name);
void test()
{
/* since interfaces are static, pMem and pVec need not be
deallocated */
Examples_Memory *pMem =
(Examples_Memory*)GetNamedInterface("Examples.Memory");
Examples_Vector *pVec =
(Examples_Vector*)GetNamedInterface("Examples.Vector");
void *v1 = pMem->allocate(sizeof(int[4]));
void *v2 = pVec->create(4);
pVec->set(v1, 2, 42);
pVec->set(v2, 0, pVec->get(v1, 2));
pMem->deallocate(v1);
pMem->deallocate(v2);
}
</file>
Typically the client would have loaded a dynamically linked library and
found the address of the published
GetNamedInterface function. Once that function is avaible, it is easy to
access all the remaining functions
via the named interfaces.
</snip>
------------------------------
Date: 12 Nov 2002 11:49:15 -0800
From: shaffer@lyris.com (Anthony Shaffer Lyris)
Subject: Building Perl on Windows as Static Library (as opposed to a DLL)
Message-Id: <49fc6c1b.0211121149.18237dca@posting.google.com>
I've been trying to compile Perl (5.6.1) as static lib under Windows (XP)
using Visual C++ as a static library without any success. I can build Perl
as a DLL without any issues. But, I want to directly link Perl into my
application so I don't have any extra files (e.g. Perl56.dll) which is
why I want to build it as a static library. I can't find anything
obvious in the Makefile to tweak nor I have seen anying posting or other web
pages about this. Am I missing something and/or has
someone done this already? Thanks in advance for any help!
--Anthony Shaffer
Lyris Technologies
------------------------------
Date: Tue, 12 Nov 2002 14:08:53 -0800
From: "Brandon L" <spam@digitaltension.com>
Subject: DBI, mysql, how do I get the results into an array without
Message-Id: <ut2v0bfo5228ad@corp.supernews.com>
I keep getting this error in my logs. I cant figure out the problem. Below
is my script I am using, I am a novice-intermediate scripter (aka i dont
know that much). This use to generate a lot more errors but it only does one
error per page view now.
DBD::mysql::st fetchrow_array failed: fetch() without execute() at
./inc/common.inc line 109.
So first I make a sub to connect, this part seems to work
sub sqlConnect {
$dbh = DBI->connect("DBI:mysql:database=$sqlDatabase;host=$sqlHost",
$sqlUsername, $sqlPassword);
}
next, in various parts of my script i use this sub like this:
$query = qq~SELECT * FROM database WHERE 1~;
sqlQuery($query);
I am then returned with @sqlResults which i split into variables and use.
sub sqlQuery {
undef(@sqlResults);
$myQuery = "$_[0]";
$sth = $dbh->prepare($myQuery);
# Shouldnt this fix the fethrow_array failed without execution error?
$rv = $sth->execute or die "executing: ", $dbh->errstr;
while (@sqlArray = $sth->fetchrow_array) {
@sqlArray = join ("|", @sqlArray);
push(@sqlResults, "@sqlArray");
}
# Clear sqlArray
undef(@sqlArray);
# $numRows = $sth->rows;
}
At the end of my script i disconnect, i think
sub sqlDisconnect {
$rc = $sth->finish;
$rc = $dbh->disconnect;
}
------------------------------
Date: 12 Nov 2002 20:43:19 GMT
From: "Tassilo v. Parseval" <tassilo.parseval@post.rwth-aachen.de>
Subject: Re: Global file search function?
Message-Id: <aqrp57$lo3$1@nets3.rz.RWTH-Aachen.DE>
Also sprach tk:
> In a fit of excitement on 12 Nov 2002 07:40:21 -0800,
> rook_5150@yahoo.com (Bryan Castillo) managed to scribble:
>| The locate program uses an indexed database (at least the
>| implementations I know of). It will be alot faster than File::Find.
>| Too bad locate hasn't been complete d yet, for Perl Power Tools.
>
> [d:\home\tk]$ locate
> 'locate' is not recognized as an internal or external command,
> operable program or batch file.
>
> Kind of leaves me screwed, if I tried to run the script on this box.
>
> As I said, system() isn't portable.
Why should the OP bother to make his programs also run on your computer?
I certainly couldn't care less about portability unless I _explicitely_
plan to make it portable.
Tassilo
--
$_=q!",}])(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus;})(rekcah{lrePbus;})(lreP{rehtonabus;})(rehtona{tsuJbus!;
$_=reverse;s/sub/(reverse"bus").chr(32)/xge;tr~\n~~d;eval;
------------------------------
Date: 12 Nov 2002 13:16:08 -0800
From: rook_5150@yahoo.com (Bryan Castillo)
Subject: Re: Global file search function?
Message-Id: <1bff1830.0211121316.69842b12@posting.google.com>
>
> | > |
> | > | There is ofcourse the GNU "locate" command. Perhaps already
> | > | installed on your system...
> | >
> | > WHy on earth would you want to use a system call when you can do it
> | > quite as easily in Perl that's portable?
Please show me the "portable" perl code that finds zip files on my
system as easily and fast as the "non-portable evil code using system"
below.
bryanc@psylocke bryanc]$ perl findzips.pl
[34] files found in [0.222070] seconds.
[bryanc@psylocke bryanc]$ cat findzips.pl
#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes qw(time);
my $s = time;
my @files;
open(P, "locate *.zip |") || die;
while (<P>) { chomp; push(@files, $_); }
my $e = time;
printf "[%d] files found in [%f] seconds.\n", ($#files+1), $e-$s;
> | >
> | >
> | > tk
> |
> | The locate program uses an indexed database (at least the
> | implementations I know of). It will be alot faster than File::Find.
> | Too bad locate hasn't been complete d yet, for Perl Power Tools.
>
> [d:\home\tk]$ locate
> 'locate' is not recognized as an internal or external command,
> operable program or batch file.
>
> Kind of leaves me screwed, if I tried to run the script on this box.
>
Running anything on that box, kind of leaves you screwed. (IMHO)
Would you make a similar argument if perl weren't installed on the
box?
> As I said, system() isn't portable.
>
Perhaps, you should program in java? Won't that run on a ball point
pen? :)
File::Find makes your perl code more portable than using locate
(assuming perl is installed). However, system is portable and locate
is portable. You could tell the gnu folks that all their work put
into autoconf is worthless. There are people who have ported locate
to more than one unix system and to cygwin, possibly others. I can
use system() on many systems and languages.
There are very few programs that aren't portable, it's just that the
amount of work taken to port them may differ.
If you:
- want ALOT MORE SPEED than File::Find
- you have locate installed
- you can handle a little less "portability"
- you don't care about possible false positives
- and failures to find recently created files
locate is good choice
Remember, you asked for any reason on Earth,
^^^^^^^^^^^^^^^^^^^
begging for someone to be devil's advocate.
------------------------------
Date: Tue, 12 Nov 2002 22:01:49 GMT
From: tk <tk@WINDOZEdigiserv.net>
Subject: Re: Global file search function?
Message-Id: <iqt2tu4prutct9qa04t128hc7kj8mc6cq2@4ax.com>
-----BEGIN xxx SIGNED MESSAGE-----
Hash: SHA1
In a fit of excitement on 12 Nov 2002 13:16:08 -0800,
rook_5150@yahoo.com (Bryan Castillo) managed to scribble:
[snip]
| > Kind of leaves me screwed, if I tried to run the script on this
| > box.
| >
|
| Running anything on that box, kind of leaves you screwed. (IMHO)
| Would you make a similar argument if perl weren't installed on the
| box?
I'm not a windoze lover. It's mainly used for GFX apps (Photoshop,
Poser, Bryce etc) as IMHO, the gimp isn't as good; but that's for me,
my opinion.
Most of my code runs on FreeBSD, where indeed, locate would serve as a
fast option, but that's fine, if you only run the script on that OS
(don't know if Linux has 'locate', never tried any flavour).
If Perl wasn't installed, I wouldn't attempt to run a Perl script on
the box. The fact that another method can be used to achive the same
results on any platform, renders IMO, File::Find() a better option, but
would depend if you're writing the script for an OS specifically that
has the 'locate' command installed.
|
|
| > As I said, system() isn't portable.
| >
| Perhaps, you should program in java? Won't that run on a ball point
| pen? :)
heh, no idea.
For the most part, I code in PHP for Web development, Perl for system
scripting as I _personally_ find that they each have their strong
points within their own tasks.
|
|
| File::Find makes your perl code more portable than using locate
| (assuming perl is installed). However, system is portable and locate
| is portable.
I realise now, that "...system() isn't portable" was a bad statement to
make, as it matters not as to what platform the script is executed on,
it's the data between the ( ) that enables it to be portable or not.
| You could tell the gnu folks that all their work put
| into autoconf is worthless. There are people who have ported locate
| to more than one unix system and to cygwin, possibly others.
You've mentioned *NIX environments. What about Windoze itself? some
people run NT as their servers, I haven't checked, but is locate ported
to win32/dos too?
| I can use system() on many systems and languages.
As can I.
| There are very few programs that aren't portable, it's just that the
| amount of work taken to port them may differ.
True, but if you dont have to have millisecond results, would it not be
easier to write portable code from the outset, instead of either having
to modify the script (even moderately) for the second platform you wish
to run it on, or have to copy/install a ported command to the platform
you're working on?
_If_ the script happened to be a CGI script, running on a remote server
(not owned/have root access by yourself), the possability of
running/installing a command can cause possible issues, in that you'd
have to convince the admin to install what you require. For those of us
that run our own servers, maybe this isn't too big an issue, but for
3rd party "users" of servers, this could be quite an issue.
|
| If you:
| - want ALOT MORE SPEED than File::Find
| - you have locate installed
| - you can handle a little less "portability"
| - you don't care about possible false positives
| - and failures to find recently created files
|
| locate is good choice
|
| Remember, you asked for any reason on Earth,
| ^^^^^^^^^^^^^^^^^^^
| begging for someone to be devil's advocate.
Fair enough and above points noted =)
Regards,
tk
-----BEGIN xxx SIGNATURE-----
Version: PGP Personal Privacy 6.5.3
iQA/AwUBPdF6jSjNZg8h4REKEQJ9EACgryvPAwaBG8/w0D8AsQ+iGh+1/X8AoNU8
9gMSPJk6F677mQMx90z/mQZT
=y2Iz
-----END PGP SIGNATURE-----
--
+--------------------------+
| digiServ Network |
| Web solutions | Remove WINDOZE to reply.
| http://www.digiserv.net/ |
+--------------------------+
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 4106
***************************************