--- ./os2/OS2/REXX/DLL/DLL.pm-pre1	Wed Mar 26 14:51:44 2003
+++ ./os2/OS2/REXX/DLL/DLL.pm	Mon May 26 02:27:24 2003
@@ -20,7 +20,7 @@ sub AUTOLOAD {
 # Preloaded methods go here.  Autoload methods go after __END__, and are
 # processed by the autosplit program.
 
-# Cannot autoload, the autoloader is used for the REXX functions.
+# Cannot be autoload, the autoloader is used for the REXX functions.
 
 sub new {
   confess 'Usage: OS2::DLL->new( <file> [<dirs>] )' unless @_ >= 2;
@@ -59,27 +59,32 @@ EOE
 		"OS2::DLL::$file";
 }
 
-sub find
-{
+sub wrapper_REXX {
+	confess 'Usage: $dllhandle->wrapper_REXX($func_name)' unless @_ == 2;
 	my $self   = shift;
 	my $file   = $self->{File};
 	my $handle = $self->{Handle};
 	my $prefix = exists($self->{Prefix}) ? $self->{Prefix} : "";
 	my $queue  = $self->{Queue};
-	foreach (@_) {
-		my $name = "OS2::DLL::${file}::$_";
-		next if defined(&$name);
-		my $addr = DynaLoader::dl_find_symbol($handle, uc $prefix.$_)
-		        || DynaLoader::dl_find_symbol($handle, $prefix.$_)
-			or return 0;
-		eval <<EOE or die "eval sub";
-package OS2::DLL::$file;
-sub $_ {
-  shift;
-  OS2::DLL::_call('$_', $addr, '$queue', \@_);
+	my $name = shift;
+	$prefix = '' if $name =~ /^#\d+/;	# loading by ordinal
+	my $addr = (DynaLoader::dl_find_symbol($handle, uc $prefix.$name)
+		    || DynaLoader::dl_find_symbol($handle, $prefix.$name));
+	return sub {
+	  OS2::DLL::_call($name, $addr, $queue, @_);
+	} if $addr;
+	my $err = DynaLoader::dl_error();
+	$err =~ s/\s+at\s+\S+\s+line\s+\S+\s*\z//;
+	croak "Can't find symbol `$name' in DLL `$file': $err";
 }
-1;
-EOE
+
+sub find
+{
+	my $self   = shift;
+	my $file   = $self->{File};
+	foreach (@_) {
+		my $f = eval {$self->wrapper_REXX($_)} or return 0;
+		${"OS2::DLL::${file}::"}{$_} = $f;
 	}
 	return 1;
 }
@@ -104,6 +109,8 @@ See documentation of L<OS2::REXX> module
 	use OS2::DLL;
 	$emx_dll = OS2::DLL->load('emx');
 	$emx_version = $emx_dll->emx_revision();
+	$func_emx_version = $emx_dll->wrapper_REXX('#128'); # emx_revision
+	$emx_version = $func_emx_version->();
 
 =head1 DESCRIPTION
 
@@ -133,11 +140,23 @@ failure.
 
 	BOOL = $dll->find(NAME [, NAME [, ...]]);
 
-Returns true if all functions are available.
+Returns true if all functions are available.  As a side effect, creates
+a function with the specified name in the package constructed by the name
+of the DLL.
+
+=head2 Create a Perl wrapper (optional):
+
+	$func = $dll->wrapper_REXX(NAME);
+
+Returns a reference to a Perl function wrapper for the entry point NAME
+in the DLL.  Similar to the OS/2 API, the NAME may be C<"#123"> - in this case
+the ordinal is loaded.   Croaks with a meaningful error message if NAME does
+not exists (although the message for the case when the name is an ordinal may
+be confusing).
 
 =head2 Call external REXX function:
 
-	$dll->function(arguments);
+	$dll->function_name(arguments);
 
 Returns the return string if the return code is 0, else undef.
 Dies with error message if the function is not available.
