Call a function in a shared library: Difference between revisions

From Rosetta Code
Content added Content deleted
(added Ursala)
Line 134: Line 134:
set handle [OpenImage "/the/file/name"]</lang>
set handle [OpenImage "/the/file/name"]</lang>
Note that if the library is appropriately set up with the correct entry function, it can be accessed directly with <code>load</code> which will cause it to register a Tcl command for the functionality it exports. [http://www.swig.org SWIG] can be used to automatically generate the interface code.
Note that if the library is appropriately set up with the correct entry function, it can be accessed directly with <code>load</code> which will cause it to register a Tcl command for the functionality it exports. [http://www.swig.org SWIG] can be used to automatically generate the interface code.

=={{header|Ursala}}==
When abs(x) is evaluated, a run time check is performed for the
availability of the system library's absolute value function (fabs),
and if found, it is used. If not, the user defined replacement
function is invoked.
<lang Ursala>
#import std
#import flo

my_replacement = fleq/0.?/~& negative

abs = math.|fabs my_replacement
</lang>

Revision as of 23:37, 23 June 2009

Task
Call a function in a shared library
You are encouraged to solve this task according to the task description, using any language you may know.

Show how to call a function in a shared library (without dynamically linking to it at compile-time). In particular, show how to call the shared library function if the library is available, otherwise use an internal equivalent function.

AutoHotkey

Works with: [AutoHotkey.dll]


dllhost.ahk <lang AutoHotkey> ahkdll := DllCall("LoadLibrary", "str", "AutoHotkey.dll") clientHandle := DllCall("AutoHotkey\ahkdll", "str", "dllclient.ahk", "str" , "", "str", "parameter1 parameter2", "Cdecl Int") </lang> dllclient.ahk <lang AutoHotkey> Msgbox, hello from client </lang>

C

Works with: POSIX version .1-2001

Tested with gcc on a GNU/Linux system (on GNU/Linux dl* functions are available linking to libdl, i.e. with -ldl option)

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <dlfcn.h>

int myopenimage(const char *in) {

 static int handle=0;
 fprintf(stderr, "internal openimage opens %s...\n", in);
 return handle++;

}

int main() {

 void *imglib;
 int (*extopenimage)(const char *);
 int imghandle;
 imglib = dlopen("./fakeimglib.so", RTLD_LAZY);
 if ( imglib != NULL ) {
   /* extopenimage = (int (*)(const char *))dlsym(imglib,...)
      "man dlopen" says that C99 standard leaves casting from
      "void *" to a function pointer undefined. The following is the
      POSIX.1-2003 workaround found in man */
   *(void **)(&extopenimage) = dlsym(imglib, "openimage");
   /* the following works with gcc, gives no warning even with
      -Wall -std=c99 -pedantic options... :D */
   /* extopenimage = dlsym(imglib, "openimage"); */
   imghandle = extopenimage("fake.img");
 } else {
   imghandle = myopenimage("fake.img");
 }
 printf("opened with handle %d\n", imghandle);
 /* ... */
 if (imglib != NULL ) dlclose(imglib);
 return EXIT_SUCCESS;

}</lang>

The fake fakeimglib.so code is

<lang c>#include <stdio.h> /* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */ int openimage(const char *s) {

 static int handle = 100;
 fprintf(stderr, "opening %s\n", s);
 return handle++;

}</lang>

When the library fakeimglib.c exists in the current directory (this choice is senseful only for testing purposes), the output is:

opening fake.img
opened with handle 100

otherwise the output is:

internal openimage opens fake.img...
opened with handle 0

C#

In Windows.

<lang csharp>using System.Runtime.InteropServices;

class Program {

   [DllImport("fakelib.dll")]
   public static extern int fakefunction(int args);
   static void Main(string[] args) {
       int r = fakefunction(10);
   }

}</lang>

Python

The import statement can be done in a try/except block <lang python>try:

   import psyco
   psyco.full()
   print "# With psyco JIT compiler"

except:

   print "# Without psyco JIT compiler"
  1. Rest of program</lang>

Smalltalk

Works with: GNU Smalltalk

The code tries to load the fakeimglib (cfr C example); if it succeed, the symbol openimage will exist, and will be called; otherwise, it is executed an "internal" code for openimage. In this example return code of the function of the library is ignored (ValueHolder null)

<lang smalltalk>DLD addLibrary: 'fakeimglib'.

Object subclass: ExtLib [

 ExtLib class >> openimage: aString [
   (CFunctionDescriptor isFunction: 'openimage')
   ifTrue: [
      (CFunctionDescriptor for: 'openimage'
                           returning: #int
                           withArgs: #( #string ) ) callInto: (ValueHolder null).
   ] ifFalse: [ ('internal open image %1' % { aString }) displayNl ]
 ]

].

ExtLib openimage: 'test.png'.</lang>

Tcl

Library: Ffidl

<lang Tcl>package require Ffidl

if {[catch {

   ffidl::callout OpenImage {pointer-utf8} int [ffidl::symbol fakeimglib.so openimage]

}]} then {

   # Create the OpenImage command by other means here...

} set handle [OpenImage "/the/file/name"]</lang> Note that if the library is appropriately set up with the correct entry function, it can be accessed directly with load which will cause it to register a Tcl command for the functionality it exports. SWIG can be used to automatically generate the interface code.

Ursala

When abs(x) is evaluated, a run time check is performed for the availability of the system library's absolute value function (fabs), and if found, it is used. If not, the user defined replacement function is invoked. <lang Ursala>

  1. import std
  2. import flo

my_replacement = fleq/0.?/~& negative

abs = math.|fabs my_replacement </lang>