Call a function in a shared library: Difference between revisions
(added Ursala) |
(Added Java) |
||
Line 91: | Line 91: | ||
} |
} |
||
}</lang> |
}</lang> |
||
=={{header|Java}}== |
|||
The <tt>native</tt> keyword is the key here. |
|||
<lang java>public class LoadLib{ |
|||
private static native void functionInSharedLib(); //change return type or parameters as necessary |
|||
public static void main(String[] args){ |
|||
System.loadLibrary("Path/to/library/here/lib.dll"); |
|||
functionInSharedLib(); |
|||
} |
|||
}</lang> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
The import statement can be done in a try/except block |
The import statement can be done in a try/except block |
Revision as of 19:06, 29 July 2009
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
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
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>
- include <stdlib.h>
- 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>
Java
The native keyword is the key here. <lang java>public class LoadLib{
private static native void functionInSharedLib(); //change return type or parameters as necessary
public static void main(String[] args){ System.loadLibrary("Path/to/library/here/lib.dll"); functionInSharedLib(); }
}</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"
- Rest of program</lang>
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
<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>
- import std
- import flo
my_replacement = fleq/0.?/~& negative
abs = math.|fabs my_replacement </lang>