Call a function in a shared library: Difference between revisions
m
syntax highlighting fixup automation
m (→{{header|Ol}}) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 12:
===Windows===
The following solution calls ''MessageBox'' from [[Windows]]' dynamic library ''user32.dll''. It does not use Win32 bindings, which would be meaningless, because ''MessageBox'' is already there. Instead of that it links statically to ''kernel32.dll'', which required to load anything under [[Windows]]. From there it uses ''LoadLibrary'' to load ''user32.dll'' and then ''GetProcAddress'' to get the ''MessageBox'' entry point there. Note how [[Windows]] mangles names of functions in the import libraries. So "LoadLibrary" becomes "_LoadLibraryA@4", which is its real name. "A" means ASCII. Once address of ''MessageBox'' is obtained it is converted to a pointer to a function that has an interface corresponding to it. Note [[Windows]]' call convention, which is '''stdcall'''.
<
with Interfaces; use Interfaces;
with Interfaces.C; use Interfaces.C;
Line 56:
Put_Line ("Unable to load the library " & HANDLE'Image (Library));
end if;
end Shared_Library_Call;</
===Linux===
Here we are using the ''dl'' library statically (-ldl switch upon linking) and ''Xlib'' dynamically (''libX11.so''). The function ''dlopen'' loads a library. The function ''dlsym'' looks up for an entry point there. From ''libX11.so'', first ''XOpenDisplay'' is called to open an X11 display, which name is in the DISPLAY environment variable. Then XDisplayWidth of the display is obtained an printed into the standard output.
<
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;
Line 108:
Put_Line ("Unable to load the library");
end if;
end Shared_Library_Call;</
=={{header|Arturo}}==
<
try? [
call.external:'curl "curl_version" .expect: :string []
Line 121:
]
print ["curl version:" getCurlVersion]</
{{out}}
Line 130:
{{works with|http://www.autohotkey.net/~tinku99/ahkdll/ AutoHotkey.dll}}<br>
dllhost.ahk
<
clientHandle := DllCall("AutoHotkey\ahkdll", "str", "dllclient.ahk", "str"
, "", "str", "parameter1 parameter2", "Cdecl Int")</
dllclient.ahk
<syntaxhighlight lang
=={{header|BaCon}}==
<
PROTO j0
bessel0 = j0(1.0)
PRINT bessel0
</syntaxhighlight>
{{out}}
Line 156:
{{works with|BBC BASIC for Windows}}
The following shared libraries are automatically available: ADVAPI32.DLL, COMCTL32.DLL, COMDLG32.DLL, GDI32.DLL, KERNEL32.DLL, SHELL32.DLL, USER32.DLL and WINMM.DLL.
<
</syntaxhighlight>
=={{header|C}}==
Line 164:
'''Tested with''' gcc on a GNU/Linux system (on GNU/Linux <code>dl*</code> functions are available linking to <tt>libdl</tt>, i.e. with <tt>-ldl</tt> option)
<
#include <stdlib.h>
#include <dlfcn.h>
Line 199:
if (imglib != NULL ) dlclose(imglib);
return EXIT_SUCCESS;
}</
The fake <tt>fakeimglib.so</tt> code is
<
/* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */
int openimage(const char *s)
Line 210:
fprintf(stderr, "opening %s\n", s);
return handle++;
}</
When the library <tt>fakeimglib.so</tt> exists in the current directory (this choice is senseful only for testing purposes), the output is:
Line 224:
=={{header|C sharp|C#}}==
In Windows.
<
class Program {
Line 233:
int r = fakefunction(10);
}
}</
=={{header|COBOL}}==
Tested with GnuCOBOL, GNU/Linux.
<
program-id. callsym.
Line 274:
goback.
end program callsym.</
{{out}}
Line 284:
{{libheader|CFFI}}
<
#<CFFI::FOREIGN-LIBRARY {1004F4ECC1}>
CL-USER> (cffi:foreign-funcall "XOpenDisplay"
Line 290:
#-sbcl ":0.0"
:pointer)
#.(SB-SYS:INT-SAP #X00650FD0)</
=={{header|Crystal}}==
<
sqrtptr = LibC.dlsym(libm, "sqrt") unless libm.null?
Line 304:
end
puts "the sqrt of 4 is #{sqrtproc.call(4.0)}"</
=={{header|D}}==
<
import std.stdio, std.c.windows.windows;
Line 315:
void main() {
writeln(GetDoubleClickTime());
}</
<pre>500</pre>
Line 322:
add.c
<syntaxhighlight lang=c>
int add(int num1, int num2) {
return num1 + num2;
}
</syntaxhighlight>
Dart code
<
show DynamicLibrary, NativeFunction, Int32;
Line 341:
print( add( 1, 2 ) );
}
</syntaxhighlight>
=={{header|Delphi}}==
Line 348:
Loads library on startup.
<
Line 354:
Loads library on first call to DoSomething.
<
Line 360:
Loads and unloads library on demand.
<
lLibraryHandle: THandle;
lDoSomething: procedure; stdcall;
Line 371:
FreeLibrary(lLibraryHandle);
end;
end;</
=={{header|Forth}}==
===GNU Forth 0.7.9 on Linux===
Call tgamma() from limbm.so
<
c-library math
Line 384:
end-c-library
</syntaxhighlight>
{{Out}}
<pre>
Line 398:
A simple "C" function add_n in add_n.c
<syntaxhighlight lang=c>
double add_n(double* a, double* b)
{
return *a + *b;
}
</
compile it
Line 412:
File add_nf.f90
<
function add_nf(a,b) bind(c, name='add_nf')
use, intrinsic :: iso_c_binding
Line 421:
add_nf = a + b
end function add_nf
</
Compile it
Line 434:
File shared_lib_new_test.f90
<
!-----------------------------------------------------------------------
!module dll_module
Line 710:
end program test_load_dll
</syntaxhighlight>
Compile test program
Line 732:
===Intel Fortran on Windows===
First, the DLL. Compile with '''ifort /dll dllfun.f90'''. The function is compiled with the STDCALL calling convention: it's not necessary here but it shows how to do it.
<
implicit none
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: FFUN
double precision :: x, y, ffun
ffun = x + y * y
end function</
Now, the main program. It will wait for two numbers and compute the result with the DLL function. Compile with '''ifort dynload.f90'''. Three functions of the Kernel32 library are necessary, see '''[https://msdn.microsoft.com/en-us/library/ms684175.aspx LoadLibrary]''', '''[https://msdn.microsoft.com/en-us/library/ms683212.aspx GetProcAddress]''' and '''[https://msdn.microsoft.com/en-us/library/ms683152.aspx FreeLibrary]''' in the MSDN. The kernel32 module is provided with the Intel Fortran compiler. The DLL has to be in a directory in the PATH environment variable.
<
use kernel32
use iso_c_binding
Line 770:
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary"
end program</
=== GNU Fortran on Windows ===
Line 784:
First the DLL:
<
implicit none
!GCC$ ATTRIBUTES DLLEXPORT, STDCALL :: FFUN
double precision :: x, y, ffun
ffun = x + y * y
end function</
Main program:
<
use kernel32
use iso_c_binding
Line 821:
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary"
end program</
Interface module:
<
use iso_c_binding
implicit none
Line 858:
end function
end interface
end module</
=={{header|FreeBASIC}}==
<
' Attempt to call Beep function in Win32 API
Line 883:
Print
Print "Press any key to quit"
Sleep</
=={{header|Go}}==
Line 892:
This is the C code to produce fakeimglib.so:
<
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */
int openimage(const char *s)
Line 899:
fprintf(stderr, "opening %s\n", s);
return handle++;
}</
And this is the Go code to dynamically load the .so file and call the 'openimage' function - or if the .so file (or the function itself) is not available, to call the internal version of the function:
<
/*
Line 952:
}
fmt.Printf("opened with handle %d\n", imghandle)
}</
{{output}}
Line 964:
{{libheader|unix}}
<
-- stack --resolver lts-6.33 --install-ghc runghc --package unix
Line 1,004:
Right f -> ("Using BUF_reverse from OpenSSL", f)
putStrLn msg
putStrLn $ rev "a man a plan a canal panama"</
=={{header|J}}==
Most of this was borrowed from [[Call a foreign-language function#J]]
<
strdup=: 'msvcrt.dll _strdup >x *' cd <
free=: 'msvcrt.dll free n x' cd <
Line 1,019:
y
end.
)</
You get a domain error when the required library is not present at run time. A try/catch will let you handle this (as would the <code>::</code> adverse operator).
Example use:
<
hello
getstr@strdup ::] 'hello'
hello</
=={{header|Java}}==
Line 1,034:
If you have Unix [[make]], then edit the ''Makefile'', run <code>make</code>, run <code>java -Djava.library.path=. RSort</code>. If you don't set java.library.path, or don't build the library, then the Java code falls back from using C to using Java. For more info about building a JNI library, see [[Call a foreign-language function#Java]].
<
import java.util.Collections;
Line 1,104:
System.out.println("ok");
}
}</
<
#include <stdlib.h>
Line 1,139:
qsort(elem, length, sizeof(jint), reverse_abs_cmp);
(*jenv)->ReleasePrimitiveArrayCritical(jenv, ary, elem, 0);
}</
<
# Edit the next lines to match your JDK.
Line 1,167:
clean:
rm -f TrySort.class TrySort?IntList.class \
TrySort?ReverseAbsCmp.class TrySort.h $(LIB)</
===JNA===
{{libheader|JNA}}
<
import com.sun.jna.Native;
Line 1,185:
lib.sharedLibraryFunction();
}
}</
=={{header|Jsish}}==
Line 1,193:
Normally, this function would register commands to the shell, but this is just a DISPLAY statement on load, and then again on unload as jsish runs down. Note the name used, "Jsi_Initbyjsi", from "byjsi.so".
<
load('byjsi.so');</
For example, a COBOL library generated from
<
program-id. sample as "Jsi_Initbyjsi".
Line 1,223:
display "Called again with: " jsi-interp ", " rel upon syserr
goback.
end program sample.</
{{out}}
Line 1,234:
=={{header|Julia}}==
Julia has the `ccall` function which follows the form: ccall((symbol, library), RetType, (ArgType1, ...), ArgVar1, ...)
<
#this example works on Windows
ccall( (:GetDoubleClickTime, "User32"), stdcall,
Uint, (), )
ccall( (:clock, "libc"), Int32, ())</
For more information, see here [http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code.html]
Line 1,247:
This is the C code to produce fakeimglib.so:
<
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */
int openimage(const char *s)
Line 1,254:
fprintf(stderr, "opening %s\n", s);
return handle++;
}</
And this is the Kotlin code to dynamically load the .so file and call the 'openimage' function - or if the .so file (or the function itself) is not available, to call the internal version of the function:
<
import kotlinx.cinterop.*
Line 1,289:
}
println("opened with handle $imgHandle")
}</
{{out}}
Line 1,297:
=={{header|Lingo}}==
<
str = "The quick brown fox jumps over the lazy dog"
Line 1,314:
crc = crcObj.crc32(str)
end if</
=={{header|Lua}}==
There is no built-in mechanism, but several external library options exist. Here, the alien library is used to display a message box via the Win32 API.
<
msgbox = alien.User32.MessageBoxA
msgbox:types({ ret='long', abi='stdcall', 'long', 'string', 'string', 'long' })
retval = msgbox(0, 'Please press Yes, No or Cancel', 'The Title', 3)
print(retval) --> 6, 7 or 2</
=={{header|Maple}}==
<
> cfloor( 2.3 );
2.</
=={{header|Mathematica}}/{{header|Wolfram Language}}==
This works on windows and on linux/mac too (through Mono)
<
externalFloor = DefineDLLFunction["floor", "msvcrt.dll", "double", { "double" }];
externalFloor[4.2]
-> 4.</
=={{header|Nim}}==
===Interacting with C code===
<
echo openimage("foo")
echo openimage("bar")
echo openimage("baz")</
The fake <code>fakeimglib.so</code> code is
<
/* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */
int openimage(const char *s)
Line 1,351:
fprintf(stderr, "opening %s\n", s);
return handle++;
}</
Output:
<pre>opening foo
Line 1,361:
===Interacting with Nim code===
<
echo openimage("foo")
echo openimage("bar")
echo openimage("baz")</
The fake <code>libfakeimg.so</code> code is
<
var handle = 100
Line 1,373:
stderr.writeln "opening ", s
result = handle
inc(handle)</
Output:
<pre>opening foo
Line 1,388:
Here is an example of use of this [[Call a function in a shared library/OCaml|Dlffi module]]:
<
let get_int = function Int v -> v | _ -> failwith "get_int"
Line 1,418:
Printf.printf "# Screen dimensions are: %d x %d pixels\n" width height;
dlclose xlib;
;;</
=={{header|Ol}}==
Simplest case. Will produce memory leak, because no C "free" function called for dupped string. Useful when no "free" function call required.
<
(import (otus ffi))
Line 1,431:
(print (strdup "Hello World!"))
</syntaxhighlight>
A bit complex case. No memory leaks, because "free" function called for dupped string.
<
(import (otus ffi))
Line 1,448:
(print (strdup "Hello World!"))
</syntaxhighlight>
{{Out}}
Line 1,456:
=={{header|OxygenBasic}}==
<
'Loading a shared library at run time and calling a function.
Line 1,470:
FreeLibrary user32
</syntaxhighlight>
=={{header|PARI/GP}}==
<
where "G" is the parser code; see section 5.7.3 in the [http://pari.math.u-bordeaux.fr/pub/pari/manuals/2.4.4/libpari.pdf User's Guide to the PARI library] for more information.
Line 1,483:
===Inline===
This modules auto-builds a wrapper to the library on the first call, and subsequently uses that interface with no delay.
<
C => "DATA",
ENABLE => "AUTOWRAP",
Line 1,492:
__DATA__
__C__
double atan(double x);</
{{out}}
<pre>3.14159265358979</pre>
===FFI===
This module is smart about finding libraries, here getting <code>atan</code> (from 'lm') and <code>puts</code> (from 'libc').
<
my $ffi = FFI::Platypus->new;
$ffi->lib(undef);
Line 1,503:
$ffi->attach(atan => ['double'] => 'double');
puts(4*atan(1));</
{{out}}
<pre>3.14159265358979</pre>
=={{header|Phix}}==
<!--<
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- not from a browser, mate!</span>
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">libname</span><span style="color: #0000FF;">,</span><span style="color: #000000;">funcname</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">WINDOWS</span><span style="color: #0000FF;">?{</span><span style="color: #008000;">"user32"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CharLowerA"</span><span style="color: #0000FF;">}:{</span><span style="color: #008000;">"libc"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tolower"</span><span style="color: #0000FF;">})</span>
Line 1,518:
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">func</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- ('A'==65)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</
{{out}}
<pre>
Line 1,530:
===32-bit version===
For the 32-bit version, we need some glue code:
<
(gcc "x11" '("-lX11") 'xOpenDisplay 'xCloseDisplay)
Line 1,555:
-> 158094320
: (xCloseDisplay Display)
-> 0</
===64-bit version===
In the 64-bit version, we can call the library directly:
<
-> 6502688
: (native "/usr/lib/libX11.so.6" "XCloseDisplay" 'I Display)
-> 0</
=={{header|PowerBASIC}}==
{{Works with|PowerBASIC for Windows}}
In this example, if the library can't be found (user32), or the desired function in the library (MessageBoxA), the equivalent built-in function (MSGBOX) is at the "epicFail" label... but really, if you can't find user32.dll, you've got bigger things to worry about.
<
FUNCTION PBMAIN () AS LONG
Line 1,602:
IF ISFALSE(tmp&) THEN MSGBOX "Error freeing library... [shrug]"
END IF
END FUNCTION</
=={{header|PureBasic}}==
Older PureBasic versions normally relied on CallFunction() and CallFunctionFast()
<
*MessageBox = GetFunction(0, "MessageBoxA")
CallFunctionFast(*MessageBox, 0, "Body", "Title", 0)
CloseLibrary(0)
endif</
Since versions 4 the recommended way is via the usage of Prototypes even if the old system still is supported.
<
If OpenLibrary(0, "User32.dll")
Line 1,618:
MsgBox(0, "Hello", "World")
CloseLibrary(0)
EndIf</
=={{header|Python}}==
=== ctypes ===
Example that call User32.dll::GetDoubleClickTime() in windows.
<
user32_dll = ctypes.cdll.LoadLibrary('User32.dll')
print user32_dll.GetDoubleClickTime()</
Or, to call printf out of the C standard library:
<
>>> # libc = ctypes.cdll.msvcrt # Windows
>>> # libc = ctypes.CDLL('libc.dylib') # Mac
Line 1,634:
>>> libc.printf(b'hi there, %s\n', b'world')
hi there, world.
17</
=== CFFI ===
[https://cffi.readthedocs.io/ CFFI] isn't built into the stdlib, but, on the other hand, it works with other Python implementations like PyPy. It also has a variety of advantages and disadvantages over ctypes, even for simple cases like this:
<
>>> from cffi import FFI
>>> ffi = FFI()
Line 1,648:
>>> C.printf(b"hi there, %s.\n", arg) # call printf
hi there, world.
17</
=={{header|QB64}}==
<syntaxhighlight lang=vb>
Declare Dynamic Library "Kernel32"
Sub SetLastError (ByVal dwErr As Long)
Line 1,657:
SetLastError 20
Print GetLastError</
=={{header|R}}==
This is possible in R in only a few limited ways. If the library function one wishes to call is a (C-level) R function (of type SEXP), then one may call
<
.Call("my_lib_fun", arg1, arg2)</
It is also possible to use <code>.C()</code> and <code>.Fortran()</code> to call voids and subroutines respectively; here the return value(s) should be in the argument list (rather than merely modifying state). An example of this might look like
<
The return of the <code>.C()</code> function is an R list.
=={{header|Racket}}==
<
(require ffi/unsafe)
(define libm (ffi-lib "libm")) ; get a handle for the C math library
; look up sqrt in the math library. if we can't find it, return the builtin sqrt
(define extern-sqrt (get-ffi-obj 'sqrt libm (_fun _double -> _double)
(lambda () sqrt)))</
Output: <pre>> (extern-sqrt 42.0)
Line 1,681:
(formerly Perl 6)
{{works with|Rakudo|2018.11}}
<syntaxhighlight lang=raku
sub XOpenDisplay(Str $s --> int64) is native('X11') {*}
Line 1,693:
say "No X11 library!";
say "Use this window instead --> ⬜";
}</
{{out}}
<pre>ID = 94722089782960</pre>
Line 1,705:
The dropping of functions isn't really necessary for most REXX programs.
<
/*Note: the REGUTIL.DLL (REGina UTILity Dynamic Link Library */
Line 1,732:
exit rcd /*exit this program with RC. */
end
exit 0 /*stick a fork in it, we're all done. */</
{{out|output|text= (which happens to reflect the program's author's particular screen size for the "DOS" window):}}
<pre>
Line 1,743:
{{works with|Ruby|2.0+}}
<
module FakeImgLib
Line 1,762:
handle = FakeImgLib.openimage("path/to/image")
puts "opened with handle #{handle}"</
The next script tries to use ImageMagick. First, it tries [https://rmagick.github.io/ rmagick] from RubyGems. If that library is missing, it tries to use [http://wiki.github.com/ffi/ffi ffi] from RubyGems to call C functions in ImageMagick. (FFI is an alternative to Fiddle). If that doesn't work, it falls back to code that only handles PNG images.
Line 1,769:
{{libheader|RubyGems}}
{{works with|Ruby|1.9+}}
<
# Example:
# $ ruby imsize.rb dwarf-vs-elf.png swedish-chef.jpg
Line 1,840:
end
end
exit status</
=={{header|Rust}}==
Line 1,846:
===Unix===
<
extern crate libc;
Line 1,883:
fn builtin_cos(x: c_double) -> c_double {
x.cos()
}</
=={{header|Scala}}==
Line 1,889:
====Get free disk space====
{{libheader|net.java.dev.sna.SNA}}
<
import com.sun.jna.ptr.IntByReference
Line 1,914:
println(f"'$disk%s' ($ok%s): sectors/cluster: ${spc.getValue}%d, bytes/sector: ${bps.getValue}%d, " +
f" free-clusters: ${fc.getValue}%d, total/clusters: ${tc.getValue}%d%n")
}}</
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
The code tries to load the <tt>fakeimglib</tt> (cfr [[Call function in shared library#C|C example]]); if it succeed, the symbol <tt>openimage</tt> will exist, and will be called; otherwise, it is executed an "internal" code for <tt>openimage</tt>. In this example return code of the function of the library is ignored (<tt>ValueHolder null</tt>)
<
Object subclass: ExtLib [
Line 1,932:
].
ExtLib openimage: 'test.png'.</
=={{header|SNOBOL4}}==
{{works with|CSNOBOL4}}
This code loads the <tt>libm</tt> library into the variable <tt>ffi_m</tt> and binds the <tt>hypot()</tt> function to the variable <tt>ffi_m_hypot</tt>. (The variable names are arbitrary.) It then declares a SNOBOL4 function called <tt>hypot()</tt> which takes two <tt>double</tt>s as arguments and returns a <tt>double</tt>, binding this name to the <tt>ffi_m_hypot</tt> object returned earlier. It then outputs four hypotenuse calculations using those values.
<
ffi_m = FFI_DLOPEN('/usr/lib/x86_64-linux-gnu/libm.so')
Line 1,948:
OUTPUT = hypot(4,5)
END</
Execution looks like this:
Line 1,960:
=={{header|Tcl}}==
{{libheader|Ffidl}}
<
if {[catch {
Line 1,967:
# Create the OpenImage command by other means here...
}
set handle [OpenImage "/the/file/name"]</
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. Alternatively, [[:Category:Critcl|critcl]] can be used to allow writing glue [[C]] code directly embedded within a Tcl script.
Line 2,010:
and if found, it is used. If not, the user defined replacement
function is invoked.
<
#import flo
my_replacement = fleq/0.?/~& negative
abs = math.|fabs my_replacement</
=={{header|VBA}}==
Line 2,022:
First the DLL. Compile with '''ifort /dll vbafun.f90'''. The DLL must be in a directory in the PATH environment variable. Notice that for 32 bits VBA, DLL functions must be STDCALL, and not CDECL (the default with Intel Fortran). In 64 bits, there is only one calling convention, so it's not a problem anymore.
<
implicit none
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: ffun
double precision :: x, y, ffun
ffun = x + y * y
end function</
Here is a VBA subroutine using the DLL
<
Declare Function ffun Lib "vbafun" (ByRef x As Double, ByRef y As Double) As Double
Sub Test()
Line 2,038:
y = 10#
Debug.Print ffun(x, y)
End Sub</
=={{header|Wren}}==
{{trans|C}}
An embedded program so we can ask the C host to call the shared library function for us.
<
var RTLD_LAZY = 1
Line 2,068:
var imghandle = (imglib != null) ? imglib.call("openimage", file) : My.openimage(file)
System.print("opened with handle %(imghandle)")
if (imglib != null) imglib.close()</
<br>
We also need to create the shared library, fakeimglib.so, and place it in the current directory.
<
gcc -c -fpic fakeimglib.c
gcc -shared fakeimglib.o -o fakeimglib.so
Line 2,081:
fprintf(stderr, "opening %s\n", s);
return handle++;
}</
<br>
Finally, we embed the Wren script in the following C program, compile and run it:
<
#include <stdio.h>
Line 2,199:
free(script);
return 0;
}</
{{out}}
Line 2,208:
=={{header|X86-64 Assembly}}==
===UASM 2.52===
<
option casemap:none
Line 2,326:
ret
end
</syntaxhighlight>
It's worth pointing out that under linux, dlopen CAN return NULL WITHOUT it being an error. One SHOULD call dlerror() to check for actual errors.
{{out}}
Line 2,340:
=={{header|zkl}}==
In zkl, extensions/new objects are written in C as shared libraries. For example, big nums are implemented as a small glue library in front of GMP:
<
BN(1)+2 //--> BN(3)</
and it "just works" as all objects are "the same" whether statically or dynamically linked.
|