Call a function in a shared library: Difference between revisions
Content added Content deleted
m (→{{header|Ol}}) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 12: | Line 12: | ||
===Windows=== |
===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'''. |
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'''. |
||
< |
<syntaxhighlight lang=Ada>with Ada.Text_IO; use Ada.Text_IO; |
||
with Interfaces; use Interfaces; |
with Interfaces; use Interfaces; |
||
with Interfaces.C; use Interfaces.C; |
with Interfaces.C; use Interfaces.C; |
||
Line 56: | Line 56: | ||
Put_Line ("Unable to load the library " & HANDLE'Image (Library)); |
Put_Line ("Unable to load the library " & HANDLE'Image (Library)); |
||
end if; |
end if; |
||
end Shared_Library_Call;</ |
end Shared_Library_Call;</syntaxhighlight> |
||
===Linux=== |
===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. |
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. |
||
< |
<syntaxhighlight lang=Ada>with Ada.Environment_Variables; use Ada.Environment_Variables; |
||
with Ada.Text_IO; use Ada.Text_IO; |
with Ada.Text_IO; use Ada.Text_IO; |
||
with Interfaces; use Interfaces; |
with Interfaces; use Interfaces; |
||
Line 108: | Line 108: | ||
Put_Line ("Unable to load the library"); |
Put_Line ("Unable to load the library"); |
||
end if; |
end if; |
||
end Shared_Library_Call;</ |
end Shared_Library_Call;</syntaxhighlight> |
||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang=rebol>getCurlVersion: function [][ |
||
try? [ |
try? [ |
||
call.external:'curl "curl_version" .expect: :string [] |
call.external:'curl "curl_version" .expect: :string [] |
||
Line 121: | Line 121: | ||
] |
] |
||
print ["curl version:" getCurlVersion]</ |
print ["curl version:" getCurlVersion]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 130: | Line 130: | ||
{{works with|http://www.autohotkey.net/~tinku99/ahkdll/ AutoHotkey.dll}}<br> |
{{works with|http://www.autohotkey.net/~tinku99/ahkdll/ AutoHotkey.dll}}<br> |
||
dllhost.ahk |
dllhost.ahk |
||
< |
<syntaxhighlight lang=AutoHotkey>ahkdll := DllCall("LoadLibrary", "str", "AutoHotkey.dll") |
||
clientHandle := DllCall("AutoHotkey\ahkdll", "str", "dllclient.ahk", "str" |
clientHandle := DllCall("AutoHotkey\ahkdll", "str", "dllclient.ahk", "str" |
||
, "", "str", "parameter1 parameter2", "Cdecl Int")</ |
, "", "str", "parameter1 parameter2", "Cdecl Int")</syntaxhighlight> |
||
dllclient.ahk |
dllclient.ahk |
||
<lang |
<syntaxhighlight lang=AutoHotkey>Msgbox, hello from client</syntaxhighlight> |
||
=={{header|BaCon}}== |
=={{header|BaCon}}== |
||
< |
<syntaxhighlight lang=qbasic>' Call a dynamic library function |
||
PROTO j0 |
PROTO j0 |
||
bessel0 = j0(1.0) |
bessel0 = j0(1.0) |
||
PRINT bessel0 |
PRINT bessel0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 156: | Line 156: | ||
{{works with|BBC BASIC for Windows}} |
{{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. |
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 lang=bbcbasic> SYS "MessageBox", @hwnd%, "This is a test message", 0, 0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Line 164: | 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) |
'''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) |
||
< |
<syntaxhighlight lang=c>#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <dlfcn.h> |
#include <dlfcn.h> |
||
Line 199: | Line 199: | ||
if (imglib != NULL ) dlclose(imglib); |
if (imglib != NULL ) dlclose(imglib); |
||
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
||
}</ |
}</syntaxhighlight> |
||
The fake <tt>fakeimglib.so</tt> code is |
The fake <tt>fakeimglib.so</tt> code is |
||
< |
<syntaxhighlight lang=c>#include <stdio.h> |
||
/* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */ |
/* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */ |
||
int openimage(const char *s) |
int openimage(const char *s) |
||
Line 210: | Line 210: | ||
fprintf(stderr, "opening %s\n", s); |
fprintf(stderr, "opening %s\n", s); |
||
return handle++; |
return handle++; |
||
}</ |
}</syntaxhighlight> |
||
When the library <tt>fakeimglib.so</tt> exists in the current directory (this choice is senseful only for testing purposes), the output is: |
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: | Line 224: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
In Windows. |
In Windows. |
||
< |
<syntaxhighlight lang=csharp>using System.Runtime.InteropServices; |
||
class Program { |
class Program { |
||
Line 233: | Line 233: | ||
int r = fakefunction(10); |
int r = fakefunction(10); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
Tested with GnuCOBOL, GNU/Linux. |
Tested with GnuCOBOL, GNU/Linux. |
||
< |
<syntaxhighlight lang=cobol> identification division. |
||
program-id. callsym. |
program-id. callsym. |
||
Line 274: | Line 274: | ||
goback. |
goback. |
||
end program callsym.</ |
end program callsym.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 284: | Line 284: | ||
{{libheader|CFFI}} |
{{libheader|CFFI}} |
||
< |
<syntaxhighlight lang=lisp>CL-USER> (cffi:load-foreign-library "libX11.so") |
||
#<CFFI::FOREIGN-LIBRARY {1004F4ECC1}> |
#<CFFI::FOREIGN-LIBRARY {1004F4ECC1}> |
||
CL-USER> (cffi:foreign-funcall "XOpenDisplay" |
CL-USER> (cffi:foreign-funcall "XOpenDisplay" |
||
Line 290: | Line 290: | ||
#-sbcl ":0.0" |
#-sbcl ":0.0" |
||
:pointer) |
:pointer) |
||
#.(SB-SYS:INT-SAP #X00650FD0)</ |
#.(SB-SYS:INT-SAP #X00650FD0)</syntaxhighlight> |
||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
< |
<syntaxhighlight lang=ruby>libm = LibC.dlopen("libm.so.6", LibC::RTLD_LAZY) |
||
sqrtptr = LibC.dlsym(libm, "sqrt") unless libm.null? |
sqrtptr = LibC.dlsym(libm, "sqrt") unless libm.null? |
||
Line 304: | Line 304: | ||
end |
end |
||
puts "the sqrt of 4 is #{sqrtproc.call(4.0)}"</ |
puts "the sqrt of 4 is #{sqrtproc.call(4.0)}"</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang=d>pragma(lib, "user32.lib"); |
||
import std.stdio, std.c.windows.windows; |
import std.stdio, std.c.windows.windows; |
||
Line 315: | Line 315: | ||
void main() { |
void main() { |
||
writeln(GetDoubleClickTime()); |
writeln(GetDoubleClickTime()); |
||
}</ |
}</syntaxhighlight> |
||
<pre>500</pre> |
<pre>500</pre> |
||
Line 322: | Line 322: | ||
add.c |
add.c |
||
<syntaxhighlight lang=c> |
|||
<lang c> |
|||
int add(int num1, int num2) { |
int add(int num1, int num2) { |
||
return num1 + num2; |
return num1 + num2; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Dart code |
Dart code |
||
< |
<syntaxhighlight lang=javascript>import 'dart:ffi' |
||
show DynamicLibrary, NativeFunction, Int32; |
show DynamicLibrary, NativeFunction, Int32; |
||
Line 341: | Line 341: | ||
print( add( 1, 2 ) ); |
print( add( 1, 2 ) ); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
Line 348: | Line 348: | ||
Loads library on startup. |
Loads library on startup. |
||
< |
<syntaxhighlight lang=Delphi>procedure DoSomething; external 'MYLIB.DLL';</syntaxhighlight> |
||
Line 354: | Line 354: | ||
Loads library on first call to DoSomething. |
Loads library on first call to DoSomething. |
||
< |
<syntaxhighlight lang=Delphi>procedure DoSomething; external 'MYLIB.DLL' delayed;</syntaxhighlight> |
||
Line 360: | Line 360: | ||
Loads and unloads library on demand. |
Loads and unloads library on demand. |
||
< |
<syntaxhighlight lang=Delphi>var |
||
lLibraryHandle: THandle; |
lLibraryHandle: THandle; |
||
lDoSomething: procedure; stdcall; |
lDoSomething: procedure; stdcall; |
||
Line 371: | Line 371: | ||
FreeLibrary(lLibraryHandle); |
FreeLibrary(lLibraryHandle); |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
===GNU Forth 0.7.9 on Linux=== |
===GNU Forth 0.7.9 on Linux=== |
||
Call tgamma() from limbm.so |
Call tgamma() from limbm.so |
||
< |
<syntaxhighlight lang=Forth> |
||
c-library math |
c-library math |
||
Line 384: | Line 384: | ||
end-c-library |
end-c-library |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 398: | Line 398: | ||
A simple "C" function add_n in add_n.c |
A simple "C" function add_n in add_n.c |
||
<syntaxhighlight lang=c> |
|||
<lang c> |
|||
double add_n(double* a, double* b) |
double add_n(double* a, double* b) |
||
{ |
{ |
||
return *a + *b; |
return *a + *b; |
||
} |
} |
||
</ |
</syntaxhighlight> |
||
compile it |
compile it |
||
Line 412: | Line 412: | ||
File add_nf.f90 |
File add_nf.f90 |
||
< |
<syntaxhighlight lang=fortran> |
||
function add_nf(a,b) bind(c, name='add_nf') |
function add_nf(a,b) bind(c, name='add_nf') |
||
use, intrinsic :: iso_c_binding |
use, intrinsic :: iso_c_binding |
||
Line 421: | Line 421: | ||
add_nf = a + b |
add_nf = a + b |
||
end function add_nf |
end function add_nf |
||
</ |
</syntaxhighlight> |
||
Compile it |
Compile it |
||
Line 434: | Line 434: | ||
File shared_lib_new_test.f90 |
File shared_lib_new_test.f90 |
||
< |
<syntaxhighlight lang=fortran> |
||
!----------------------------------------------------------------------- |
!----------------------------------------------------------------------- |
||
!module dll_module |
!module dll_module |
||
Line 710: | Line 710: | ||
end program test_load_dll |
end program test_load_dll |
||
</syntaxhighlight> |
|||
</lang> |
|||
Compile test program |
Compile test program |
||
Line 732: | Line 732: | ||
===Intel Fortran on Windows=== |
===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. |
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. |
||
< |
<syntaxhighlight lang=fortran>function ffun(x, y) |
||
implicit none |
implicit none |
||
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: FFUN |
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: FFUN |
||
double precision :: x, y, ffun |
double precision :: x, y, ffun |
||
ffun = x + y * y |
ffun = x + y * y |
||
end function</ |
end function</syntaxhighlight> |
||
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. |
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. |
||
< |
<syntaxhighlight lang=fortran>program dynload |
||
use kernel32 |
use kernel32 |
||
use iso_c_binding |
use iso_c_binding |
||
Line 770: | Line 770: | ||
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary" |
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary" |
||
end program</ |
end program</syntaxhighlight> |
||
=== GNU Fortran on Windows === |
=== GNU Fortran on Windows === |
||
Line 784: | Line 784: | ||
First the DLL: |
First the DLL: |
||
< |
<syntaxhighlight lang=fortran>function ffun(x, y) |
||
implicit none |
implicit none |
||
!GCC$ ATTRIBUTES DLLEXPORT, STDCALL :: FFUN |
!GCC$ ATTRIBUTES DLLEXPORT, STDCALL :: FFUN |
||
double precision :: x, y, ffun |
double precision :: x, y, ffun |
||
ffun = x + y * y |
ffun = x + y * y |
||
end function</ |
end function</syntaxhighlight> |
||
Main program: |
Main program: |
||
< |
<syntaxhighlight lang=fortran>program dynload |
||
use kernel32 |
use kernel32 |
||
use iso_c_binding |
use iso_c_binding |
||
Line 821: | Line 821: | ||
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary" |
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary" |
||
end program</ |
end program</syntaxhighlight> |
||
Interface module: |
Interface module: |
||
< |
<syntaxhighlight lang=fortran>module kernel32 |
||
use iso_c_binding |
use iso_c_binding |
||
implicit none |
implicit none |
||
Line 858: | Line 858: | ||
end function |
end function |
||
end interface |
end interface |
||
end module</ |
end module</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang=freebasic>' FB 1.05.0 Win64 |
||
' Attempt to call Beep function in Win32 API |
' Attempt to call Beep function in Win32 API |
||
Line 883: | Line 883: | ||
Print |
Print |
||
Print "Press any key to quit" |
Print "Press any key to quit" |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 892: | Line 892: | ||
This is the C code to produce fakeimglib.so: |
This is the C code to produce fakeimglib.so: |
||
< |
<syntaxhighlight lang=c>#include <stdio.h> |
||
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */ |
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */ |
||
int openimage(const char *s) |
int openimage(const char *s) |
||
Line 899: | Line 899: | ||
fprintf(stderr, "opening %s\n", s); |
fprintf(stderr, "opening %s\n", s); |
||
return handle++; |
return handle++; |
||
}</ |
}</syntaxhighlight> |
||
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: |
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: |
||
< |
<syntaxhighlight lang=go>package main |
||
/* |
/* |
||
Line 952: | Line 952: | ||
} |
} |
||
fmt.Printf("opened with handle %d\n", imghandle) |
fmt.Printf("opened with handle %d\n", imghandle) |
||
}</ |
}</syntaxhighlight> |
||
{{output}} |
{{output}} |
||
Line 964: | Line 964: | ||
{{libheader|unix}} |
{{libheader|unix}} |
||
< |
<syntaxhighlight lang=haskell>#!/usr/bin/env stack |
||
-- stack --resolver lts-6.33 --install-ghc runghc --package unix |
-- stack --resolver lts-6.33 --install-ghc runghc --package unix |
||
Line 1,004: | Line 1,004: | ||
Right f -> ("Using BUF_reverse from OpenSSL", f) |
Right f -> ("Using BUF_reverse from OpenSSL", f) |
||
putStrLn msg |
putStrLn msg |
||
putStrLn $ rev "a man a plan a canal panama"</ |
putStrLn $ rev "a man a plan a canal panama"</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Most of this was borrowed from [[Call a foreign-language function#J]] |
Most of this was borrowed from [[Call a foreign-language function#J]] |
||
< |
<syntaxhighlight lang=J>require 'dll' |
||
strdup=: 'msvcrt.dll _strdup >x *' cd < |
strdup=: 'msvcrt.dll _strdup >x *' cd < |
||
free=: 'msvcrt.dll free n x' cd < |
free=: 'msvcrt.dll free n x' cd < |
||
Line 1,019: | Line 1,019: | ||
y |
y |
||
end. |
end. |
||
)</ |
)</syntaxhighlight> |
||
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). |
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: |
Example use: |
||
< |
<syntaxhighlight lang=J> DupStr 'hello' |
||
hello |
hello |
||
getstr@strdup ::] 'hello' |
getstr@strdup ::] 'hello' |
||
hello</ |
hello</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 1,034: | 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]]. |
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]]. |
||
< |
<syntaxhighlight lang=java>/* TrySort.java */ |
||
import java.util.Collections; |
import java.util.Collections; |
||
Line 1,104: | Line 1,104: | ||
System.out.println("ok"); |
System.out.println("ok"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=c>/* TrySort.c */ |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 1,139: | Line 1,139: | ||
qsort(elem, length, sizeof(jint), reverse_abs_cmp); |
qsort(elem, length, sizeof(jint), reverse_abs_cmp); |
||
(*jenv)->ReleasePrimitiveArrayCritical(jenv, ary, elem, 0); |
(*jenv)->ReleasePrimitiveArrayCritical(jenv, ary, elem, 0); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=make># Makefile |
||
# Edit the next lines to match your JDK. |
# Edit the next lines to match your JDK. |
||
Line 1,167: | Line 1,167: | ||
clean: |
clean: |
||
rm -f TrySort.class TrySort?IntList.class \ |
rm -f TrySort.class TrySort?IntList.class \ |
||
TrySort?ReverseAbsCmp.class TrySort.h $(LIB)</ |
TrySort?ReverseAbsCmp.class TrySort.h $(LIB)</syntaxhighlight> |
||
===JNA=== |
===JNA=== |
||
{{libheader|JNA}} |
{{libheader|JNA}} |
||
< |
<syntaxhighlight lang=java>import com.sun.jna.Library; |
||
import com.sun.jna.Native; |
import com.sun.jna.Native; |
||
Line 1,185: | Line 1,185: | ||
lib.sharedLibraryFunction(); |
lib.sharedLibraryFunction(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Jsish}}== |
=={{header|Jsish}}== |
||
Line 1,193: | 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". |
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". |
||
< |
<syntaxhighlight lang=javascript>#!/usr/local/bin/jsish |
||
load('byjsi.so');</ |
load('byjsi.so');</syntaxhighlight> |
||
For example, a COBOL library generated from |
For example, a COBOL library generated from |
||
< |
<syntaxhighlight lang=COBOL> identification division. |
||
program-id. sample as "Jsi_Initbyjsi". |
program-id. sample as "Jsi_Initbyjsi". |
||
Line 1,223: | Line 1,223: | ||
display "Called again with: " jsi-interp ", " rel upon syserr |
display "Called again with: " jsi-interp ", " rel upon syserr |
||
goback. |
goback. |
||
end program sample.</ |
end program sample.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,234: | Line 1,234: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Julia has the `ccall` function which follows the form: ccall((symbol, library), RetType, (ArgType1, ...), ArgVar1, ...) |
Julia has the `ccall` function which follows the form: ccall((symbol, library), RetType, (ArgType1, ...), ArgVar1, ...) |
||
< |
<syntaxhighlight lang=julia> |
||
#this example works on Windows |
#this example works on Windows |
||
ccall( (:GetDoubleClickTime, "User32"), stdcall, |
ccall( (:GetDoubleClickTime, "User32"), stdcall, |
||
Uint, (), ) |
Uint, (), ) |
||
ccall( (:clock, "libc"), Int32, ())</ |
ccall( (:clock, "libc"), Int32, ())</syntaxhighlight> |
||
For more information, see here [http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code.html] |
For more information, see here [http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code.html] |
||
Line 1,247: | Line 1,247: | ||
This is the C code to produce fakeimglib.so: |
This is the C code to produce fakeimglib.so: |
||
< |
<syntaxhighlight lang=C>#include <stdio.h> |
||
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */ |
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */ |
||
int openimage(const char *s) |
int openimage(const char *s) |
||
Line 1,254: | Line 1,254: | ||
fprintf(stderr, "opening %s\n", s); |
fprintf(stderr, "opening %s\n", s); |
||
return handle++; |
return handle++; |
||
}</ |
}</syntaxhighlight> |
||
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: |
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: |
||
< |
<syntaxhighlight lang=scala>// Kotlin Native version 0.5 |
||
import kotlinx.cinterop.* |
import kotlinx.cinterop.* |
||
Line 1,289: | Line 1,289: | ||
} |
} |
||
println("opened with handle $imgHandle") |
println("opened with handle $imgHandle") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,297: | Line 1,297: | ||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
< |
<syntaxhighlight lang=lingo>-- calculate CRC-32 checksum |
||
str = "The quick brown fox jumps over the lazy dog" |
str = "The quick brown fox jumps over the lazy dog" |
||
Line 1,314: | Line 1,314: | ||
crc = crcObj.crc32(str) |
crc = crcObj.crc32(str) |
||
end if</ |
end if</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{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. |
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. |
||
< |
<syntaxhighlight lang=lua>alien = require("alien") |
||
msgbox = alien.User32.MessageBoxA |
msgbox = alien.User32.MessageBoxA |
||
msgbox:types({ ret='long', abi='stdcall', 'long', 'string', 'string', 'long' }) |
msgbox:types({ ret='long', abi='stdcall', 'long', 'string', 'string', 'long' }) |
||
retval = msgbox(0, 'Please press Yes, No or Cancel', 'The Title', 3) |
retval = msgbox(0, 'Please press Yes, No or Cancel', 'The Title', 3) |
||
print(retval) --> 6, 7 or 2</ |
print(retval) --> 6, 7 or 2</syntaxhighlight> |
||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang=Maple>> cfloor := define_external( floor, s::float[8], RETURN::float[8], LIB = "libm.so" ): |
||
> cfloor( 2.3 ); |
> cfloor( 2.3 ); |
||
2.</ |
2.</syntaxhighlight> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
This works on windows and on linux/mac too (through Mono) |
This works on windows and on linux/mac too (through Mono) |
||
< |
<syntaxhighlight lang=Mathematica>Needs["NETLink`"]; |
||
externalFloor = DefineDLLFunction["floor", "msvcrt.dll", "double", { "double" }]; |
externalFloor = DefineDLLFunction["floor", "msvcrt.dll", "double", { "double" }]; |
||
externalFloor[4.2] |
externalFloor[4.2] |
||
-> 4.</ |
-> 4.</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
===Interacting with C code=== |
===Interacting with C code=== |
||
< |
<syntaxhighlight lang=nim>proc openimage(s: cstring): cint {.importc, dynlib: "./fakeimglib.so".} |
||
echo openimage("foo") |
echo openimage("foo") |
||
echo openimage("bar") |
echo openimage("bar") |
||
echo openimage("baz")</ |
echo openimage("baz")</syntaxhighlight> |
||
The fake <code>fakeimglib.so</code> code is |
The fake <code>fakeimglib.so</code> code is |
||
< |
<syntaxhighlight lang=c>#include <stdio.h> |
||
/* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */ |
/* gcc -shared -nostartfiles fakeimglib.c -o fakeimglib.so */ |
||
int openimage(const char *s) |
int openimage(const char *s) |
||
Line 1,351: | Line 1,351: | ||
fprintf(stderr, "opening %s\n", s); |
fprintf(stderr, "opening %s\n", s); |
||
return handle++; |
return handle++; |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>opening foo |
<pre>opening foo |
||
Line 1,361: | Line 1,361: | ||
===Interacting with Nim code=== |
===Interacting with Nim code=== |
||
< |
<syntaxhighlight lang=nim>proc openimage(s: string): int {.importc, dynlib: "./libfakeimg.so".} |
||
echo openimage("foo") |
echo openimage("foo") |
||
echo openimage("bar") |
echo openimage("bar") |
||
echo openimage("baz")</ |
echo openimage("baz")</syntaxhighlight> |
||
The fake <code>libfakeimg.so</code> code is |
The fake <code>libfakeimg.so</code> code is |
||
< |
<syntaxhighlight lang=nim># nim c --app:lib fakeimg.nim |
||
var handle = 100 |
var handle = 100 |
||
Line 1,373: | Line 1,373: | ||
stderr.writeln "opening ", s |
stderr.writeln "opening ", s |
||
result = handle |
result = handle |
||
inc(handle)</ |
inc(handle)</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>opening foo |
<pre>opening foo |
||
Line 1,388: | Line 1,388: | ||
Here is an example of use of this [[Call a function in a shared library/OCaml|Dlffi module]]: |
Here is an example of use of this [[Call a function in a shared library/OCaml|Dlffi module]]: |
||
< |
<syntaxhighlight lang=ocaml>open Dlffi |
||
let get_int = function Int v -> v | _ -> failwith "get_int" |
let get_int = function Int v -> v | _ -> failwith "get_int" |
||
Line 1,418: | Line 1,418: | ||
Printf.printf "# Screen dimensions are: %d x %d pixels\n" width height; |
Printf.printf "# Screen dimensions are: %d x %d pixels\n" width height; |
||
dlclose xlib; |
dlclose xlib; |
||
;;</ |
;;</syntaxhighlight> |
||
=={{header|Ol}}== |
=={{header|Ol}}== |
||
Simplest case. Will produce memory leak, because no C "free" function called for dupped string. Useful when no "free" function call required. |
Simplest case. Will produce memory leak, because no C "free" function called for dupped string. Useful when no "free" function call required. |
||
< |
<syntaxhighlight lang=scheme> |
||
(import (otus ffi)) |
(import (otus ffi)) |
||
Line 1,431: | Line 1,431: | ||
(print (strdup "Hello World!")) |
(print (strdup "Hello World!")) |
||
</syntaxhighlight> |
|||
</lang> |
|||
A bit complex case. No memory leaks, because "free" function called for dupped string. |
A bit complex case. No memory leaks, because "free" function called for dupped string. |
||
< |
<syntaxhighlight lang=scheme> |
||
(import (otus ffi)) |
(import (otus ffi)) |
||
Line 1,448: | Line 1,448: | ||
(print (strdup "Hello World!")) |
(print (strdup "Hello World!")) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
Line 1,456: | Line 1,456: | ||
=={{header|OxygenBasic}}== |
=={{header|OxygenBasic}}== |
||
< |
<syntaxhighlight lang=oxygenbasic> |
||
'Loading a shared library at run time and calling a function. |
'Loading a shared library at run time and calling a function. |
||
Line 1,470: | Line 1,470: | ||
FreeLibrary user32 |
FreeLibrary user32 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
< |
<syntaxhighlight lang=parigp>install("function_name","G","gp_name","./test.gp.so");</syntaxhighlight> |
||
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. |
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: | Line 1,483: | ||
===Inline=== |
===Inline=== |
||
This modules auto-builds a wrapper to the library on the first call, and subsequently uses that interface with no delay. |
This modules auto-builds a wrapper to the library on the first call, and subsequently uses that interface with no delay. |
||
< |
<syntaxhighlight lang=perl>use Inline |
||
C => "DATA", |
C => "DATA", |
||
ENABLE => "AUTOWRAP", |
ENABLE => "AUTOWRAP", |
||
Line 1,492: | Line 1,492: | ||
__DATA__ |
__DATA__ |
||
__C__ |
__C__ |
||
double atan(double x);</ |
double atan(double x);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>3.14159265358979</pre> |
<pre>3.14159265358979</pre> |
||
===FFI=== |
===FFI=== |
||
This module is smart about finding libraries, here getting <code>atan</code> (from 'lm') and <code>puts</code> (from 'libc'). |
This module is smart about finding libraries, here getting <code>atan</code> (from 'lm') and <code>puts</code> (from 'libc'). |
||
< |
<syntaxhighlight lang=perl>use FFI::Platypus; |
||
my $ffi = FFI::Platypus->new; |
my $ffi = FFI::Platypus->new; |
||
$ffi->lib(undef); |
$ffi->lib(undef); |
||
Line 1,503: | Line 1,503: | ||
$ffi->attach(atan => ['double'] => 'double'); |
$ffi->attach(atan => ['double'] => 'double'); |
||
puts(4*atan(1));</ |
puts(4*atan(1));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>3.14159265358979</pre> |
<pre>3.14159265358979</pre> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--< |
<!--<syntaxhighlight lang=Phix>(notonline)--> |
||
<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: #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> |
<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: | 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: #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> |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,530: | Line 1,530: | ||
===32-bit version=== |
===32-bit version=== |
||
For the 32-bit version, we need some glue code: |
For the 32-bit version, we need some glue code: |
||
< |
<syntaxhighlight lang=PicoLisp>(load "@lib/gcc.l") |
||
(gcc "x11" '("-lX11") 'xOpenDisplay 'xCloseDisplay) |
(gcc "x11" '("-lX11") 'xOpenDisplay 'xCloseDisplay) |
||
Line 1,555: | Line 1,555: | ||
-> 158094320 |
-> 158094320 |
||
: (xCloseDisplay Display) |
: (xCloseDisplay Display) |
||
-> 0</ |
-> 0</syntaxhighlight> |
||
===64-bit version=== |
===64-bit version=== |
||
In the 64-bit version, we can call the library directly: |
In the 64-bit version, we can call the library directly: |
||
< |
<syntaxhighlight lang=PicoLisp>: (setq Display (native "/usr/lib/libX11.so.6" "XOpenDisplay" 'N ":0.0")) |
||
-> 6502688 |
-> 6502688 |
||
: (native "/usr/lib/libX11.so.6" "XCloseDisplay" 'I Display) |
: (native "/usr/lib/libX11.so.6" "XCloseDisplay" 'I Display) |
||
-> 0</ |
-> 0</syntaxhighlight> |
||
=={{header|PowerBASIC}}== |
=={{header|PowerBASIC}}== |
||
{{Works with|PowerBASIC for Windows}} |
{{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. |
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. |
||
< |
<syntaxhighlight lang=powerbasic>#INCLUDE "Win32API.inc" |
||
FUNCTION PBMAIN () AS LONG |
FUNCTION PBMAIN () AS LONG |
||
Line 1,602: | Line 1,602: | ||
IF ISFALSE(tmp&) THEN MSGBOX "Error freeing library... [shrug]" |
IF ISFALSE(tmp&) THEN MSGBOX "Error freeing library... [shrug]" |
||
END IF |
END IF |
||
END FUNCTION</ |
END FUNCTION</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
Older PureBasic versions normally relied on CallFunction() and CallFunctionFast() |
Older PureBasic versions normally relied on CallFunction() and CallFunctionFast() |
||
< |
<syntaxhighlight lang=Purebasic>if OpenLibrary(0, "USER32.DLL") |
||
*MessageBox = GetFunction(0, "MessageBoxA") |
*MessageBox = GetFunction(0, "MessageBoxA") |
||
CallFunctionFast(*MessageBox, 0, "Body", "Title", 0) |
CallFunctionFast(*MessageBox, 0, "Body", "Title", 0) |
||
CloseLibrary(0) |
CloseLibrary(0) |
||
endif</ |
endif</syntaxhighlight> |
||
Since versions 4 the recommended way is via the usage of Prototypes even if the old system still is supported. |
Since versions 4 the recommended way is via the usage of Prototypes even if the old system still is supported. |
||
< |
<syntaxhighlight lang=PureBasic>Prototype.l ProtoMessageBoxW(Window.l, Body.p-unicode, Title.p-unicode, Flags.l = 0) |
||
If OpenLibrary(0, "User32.dll") |
If OpenLibrary(0, "User32.dll") |
||
Line 1,618: | Line 1,618: | ||
MsgBox(0, "Hello", "World") |
MsgBox(0, "Hello", "World") |
||
CloseLibrary(0) |
CloseLibrary(0) |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
=== ctypes === |
=== ctypes === |
||
Example that call User32.dll::GetDoubleClickTime() in windows. |
Example that call User32.dll::GetDoubleClickTime() in windows. |
||
< |
<syntaxhighlight lang=python>import ctypes |
||
user32_dll = ctypes.cdll.LoadLibrary('User32.dll') |
user32_dll = ctypes.cdll.LoadLibrary('User32.dll') |
||
print user32_dll.GetDoubleClickTime()</ |
print user32_dll.GetDoubleClickTime()</syntaxhighlight> |
||
Or, to call printf out of the C standard library: |
Or, to call printf out of the C standard library: |
||
< |
<syntaxhighlight lang=python>>>> import ctypes |
||
>>> # libc = ctypes.cdll.msvcrt # Windows |
>>> # libc = ctypes.cdll.msvcrt # Windows |
||
>>> # libc = ctypes.CDLL('libc.dylib') # Mac |
>>> # libc = ctypes.CDLL('libc.dylib') # Mac |
||
Line 1,634: | Line 1,634: | ||
>>> libc.printf(b'hi there, %s\n', b'world') |
>>> libc.printf(b'hi there, %s\n', b'world') |
||
hi there, world. |
hi there, world. |
||
17</ |
17</syntaxhighlight> |
||
=== CFFI === |
=== 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: |
[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: |
||
< |
<syntaxhighlight lang=python> |
||
>>> from cffi import FFI |
>>> from cffi import FFI |
||
>>> ffi = FFI() |
>>> ffi = FFI() |
||
Line 1,648: | Line 1,648: | ||
>>> C.printf(b"hi there, %s.\n", arg) # call printf |
>>> C.printf(b"hi there, %s.\n", arg) # call printf |
||
hi there, world. |
hi there, world. |
||
17</ |
17</syntaxhighlight> |
||
=={{header|QB64}}== |
=={{header|QB64}}== |
||
<syntaxhighlight lang=vb> |
|||
<lang vb> |
|||
Declare Dynamic Library "Kernel32" |
Declare Dynamic Library "Kernel32" |
||
Sub SetLastError (ByVal dwErr As Long) |
Sub SetLastError (ByVal dwErr As Long) |
||
Line 1,657: | Line 1,657: | ||
SetLastError 20 |
SetLastError 20 |
||
Print GetLastError</ |
Print GetLastError</syntaxhighlight> |
||
=={{header|R}}== |
=={{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 |
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 |
||
< |
<syntaxhighlight lang=rsplus>dyn.load("my/special/R/lib.so") |
||
.Call("my_lib_fun", arg1, arg2)</ |
.Call("my_lib_fun", arg1, arg2)</syntaxhighlight> |
||
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 |
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 |
||
< |
<syntaxhighlight lang=rsplus>.C("my_lib_fun", arg1, arg2, ret)</syntaxhighlight> |
||
The return of the <code>.C()</code> function is an R list. |
The return of the <code>.C()</code> function is an R list. |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang=racket>#lang racket |
||
(require ffi/unsafe) |
(require ffi/unsafe) |
||
(define libm (ffi-lib "libm")) ; get a handle for the C math library |
(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 |
; 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) |
(define extern-sqrt (get-ffi-obj 'sqrt libm (_fun _double -> _double) |
||
(lambda () sqrt)))</ |
(lambda () sqrt)))</syntaxhighlight> |
||
Output: <pre>> (extern-sqrt 42.0) |
Output: <pre>> (extern-sqrt 42.0) |
||
Line 1,681: | Line 1,681: | ||
(formerly Perl 6) |
(formerly Perl 6) |
||
{{works with|Rakudo|2018.11}} |
{{works with|Rakudo|2018.11}} |
||
<lang |
<syntaxhighlight lang=raku line>use NativeCall; |
||
sub XOpenDisplay(Str $s --> int64) is native('X11') {*} |
sub XOpenDisplay(Str $s --> int64) is native('X11') {*} |
||
Line 1,693: | Line 1,693: | ||
say "No X11 library!"; |
say "No X11 library!"; |
||
say "Use this window instead --> ⬜"; |
say "Use this window instead --> ⬜"; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>ID = 94722089782960</pre> |
<pre>ID = 94722089782960</pre> |
||
Line 1,705: | Line 1,705: | ||
The dropping of functions isn't really necessary for most REXX programs. |
The dropping of functions isn't really necessary for most REXX programs. |
||
< |
<syntaxhighlight lang=rexx>/*REXX program calls a function (sysTextScreenSize) in a shared library (regUtil). */ |
||
/*Note: the REGUTIL.DLL (REGina UTILity Dynamic Link Library */ |
/*Note: the REGUTIL.DLL (REGina UTILity Dynamic Link Library */ |
||
Line 1,732: | Line 1,732: | ||
exit rcd /*exit this program with RC. */ |
exit rcd /*exit this program with RC. */ |
||
end |
end |
||
exit 0 /*stick a fork in it, we're all done. */</ |
exit 0 /*stick a fork in it, we're all done. */</syntaxhighlight> |
||
{{out|output|text= (which happens to reflect the program's author's particular screen size for the "DOS" window):}} |
{{out|output|text= (which happens to reflect the program's author's particular screen size for the "DOS" window):}} |
||
<pre> |
<pre> |
||
Line 1,743: | Line 1,743: | ||
{{works with|Ruby|2.0+}} |
{{works with|Ruby|2.0+}} |
||
< |
<syntaxhighlight lang=ruby>require 'fiddle/import' |
||
module FakeImgLib |
module FakeImgLib |
||
Line 1,762: | Line 1,762: | ||
handle = FakeImgLib.openimage("path/to/image") |
handle = FakeImgLib.openimage("path/to/image") |
||
puts "opened with handle #{handle}"</ |
puts "opened with handle #{handle}"</syntaxhighlight> |
||
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. |
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: | Line 1,769: | ||
{{libheader|RubyGems}} |
{{libheader|RubyGems}} |
||
{{works with|Ruby|1.9+}} |
{{works with|Ruby|1.9+}} |
||
< |
<syntaxhighlight lang=ruby># This script shows the width x height of some images. |
||
# Example: |
# Example: |
||
# $ ruby imsize.rb dwarf-vs-elf.png swedish-chef.jpg |
# $ ruby imsize.rb dwarf-vs-elf.png swedish-chef.jpg |
||
Line 1,840: | Line 1,840: | ||
end |
end |
||
end |
end |
||
exit status</ |
exit status</syntaxhighlight> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Line 1,846: | Line 1,846: | ||
===Unix=== |
===Unix=== |
||
< |
<syntaxhighlight lang=rust>#![allow(unused_unsafe)] |
||
extern crate libc; |
extern crate libc; |
||
Line 1,883: | Line 1,883: | ||
fn builtin_cos(x: c_double) -> c_double { |
fn builtin_cos(x: c_double) -> c_double { |
||
x.cos() |
x.cos() |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 1,889: | Line 1,889: | ||
====Get free disk space==== |
====Get free disk space==== |
||
{{libheader|net.java.dev.sna.SNA}} |
{{libheader|net.java.dev.sna.SNA}} |
||
< |
<syntaxhighlight lang=Scala>import net.java.dev.sna.SNA |
||
import com.sun.jna.ptr.IntByReference |
import com.sun.jna.ptr.IntByReference |
||
Line 1,914: | Line 1,914: | ||
println(f"'$disk%s' ($ok%s): sectors/cluster: ${spc.getValue}%d, bytes/sector: ${bps.getValue}%d, " + |
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") |
f" free-clusters: ${fc.getValue}%d, total/clusters: ${tc.getValue}%d%n") |
||
}}</ |
}}</syntaxhighlight> |
||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
{{works with|GNU 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>) |
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>) |
||
< |
<syntaxhighlight lang=smalltalk>DLD addLibrary: 'fakeimglib'. |
||
Object subclass: ExtLib [ |
Object subclass: ExtLib [ |
||
Line 1,932: | Line 1,932: | ||
]. |
]. |
||
ExtLib openimage: 'test.png'.</ |
ExtLib openimage: 'test.png'.</syntaxhighlight> |
||
=={{header|SNOBOL4}}== |
=={{header|SNOBOL4}}== |
||
{{works with|CSNOBOL4}} |
{{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. |
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. |
||
< |
<syntaxhighlight lang=snobol4>-INCLUDE 'ffi.sno' |
||
ffi_m = FFI_DLOPEN('/usr/lib/x86_64-linux-gnu/libm.so') |
ffi_m = FFI_DLOPEN('/usr/lib/x86_64-linux-gnu/libm.so') |
||
Line 1,948: | Line 1,948: | ||
OUTPUT = hypot(4,5) |
OUTPUT = hypot(4,5) |
||
END</ |
END</syntaxhighlight> |
||
Execution looks like this: |
Execution looks like this: |
||
Line 1,960: | Line 1,960: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{libheader|Ffidl}} |
{{libheader|Ffidl}} |
||
< |
<syntaxhighlight lang=Tcl>package require Ffidl |
||
if {[catch { |
if {[catch { |
||
Line 1,967: | Line 1,967: | ||
# Create the OpenImage command by other means here... |
# Create the OpenImage command by other means here... |
||
} |
} |
||
set handle [OpenImage "/the/file/name"]</ |
set handle [OpenImage "/the/file/name"]</syntaxhighlight> |
||
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. |
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: | Line 2,010: | ||
and if found, it is used. If not, the user defined replacement |
and if found, it is used. If not, the user defined replacement |
||
function is invoked. |
function is invoked. |
||
< |
<syntaxhighlight lang=Ursala>#import std |
||
#import flo |
#import flo |
||
my_replacement = fleq/0.?/~& negative |
my_replacement = fleq/0.?/~& negative |
||
abs = math.|fabs my_replacement</ |
abs = math.|fabs my_replacement</syntaxhighlight> |
||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
Line 2,022: | 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. |
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. |
||
< |
<syntaxhighlight lang=fortran>function ffun(x, y) |
||
implicit none |
implicit none |
||
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: ffun |
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: ffun |
||
double precision :: x, y, ffun |
double precision :: x, y, ffun |
||
ffun = x + y * y |
ffun = x + y * y |
||
end function</ |
end function</syntaxhighlight> |
||
Here is a VBA subroutine using the DLL |
Here is a VBA subroutine using the DLL |
||
< |
<syntaxhighlight lang=vb>Option Explicit |
||
Declare Function ffun Lib "vbafun" (ByRef x As Double, ByRef y As Double) As Double |
Declare Function ffun Lib "vbafun" (ByRef x As Double, ByRef y As Double) As Double |
||
Sub Test() |
Sub Test() |
||
Line 2,038: | Line 2,038: | ||
y = 10# |
y = 10# |
||
Debug.Print ffun(x, y) |
Debug.Print ffun(x, y) |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|C}} |
{{trans|C}} |
||
An embedded program so we can ask the C host to call the shared library function for us. |
An embedded program so we can ask the C host to call the shared library function for us. |
||
< |
<syntaxhighlight lang=ecmascript>/* call_shared_library_function.wren */ |
||
var RTLD_LAZY = 1 |
var RTLD_LAZY = 1 |
||
Line 2,068: | Line 2,068: | ||
var imghandle = (imglib != null) ? imglib.call("openimage", file) : My.openimage(file) |
var imghandle = (imglib != null) ? imglib.call("openimage", file) : My.openimage(file) |
||
System.print("opened with handle %(imghandle)") |
System.print("opened with handle %(imghandle)") |
||
if (imglib != null) imglib.close()</ |
if (imglib != null) imglib.close()</syntaxhighlight> |
||
<br> |
<br> |
||
We also need to create the shared library, fakeimglib.so, and place it in the current directory. |
We also need to create the shared library, fakeimglib.so, and place it in the current directory. |
||
< |
<syntaxhighlight lang=c>/* |
||
gcc -c -fpic fakeimglib.c |
gcc -c -fpic fakeimglib.c |
||
gcc -shared fakeimglib.o -o fakeimglib.so |
gcc -shared fakeimglib.o -o fakeimglib.so |
||
Line 2,081: | Line 2,081: | ||
fprintf(stderr, "opening %s\n", s); |
fprintf(stderr, "opening %s\n", s); |
||
return handle++; |
return handle++; |
||
}</ |
}</syntaxhighlight> |
||
<br> |
<br> |
||
Finally, we embed the Wren script in the following C program, compile and run it: |
Finally, we embed the Wren script in the following C program, compile and run it: |
||
< |
<syntaxhighlight lang=c>/* gcc call_shared_library_function.c -o call_shared_library_function -ldl -lwren -lm */ |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 2,199: | Line 2,199: | ||
free(script); |
free(script); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,208: | Line 2,208: | ||
=={{header|X86-64 Assembly}}== |
=={{header|X86-64 Assembly}}== |
||
===UASM 2.52=== |
===UASM 2.52=== |
||
< |
<syntaxhighlight lang=asm> |
||
option casemap:none |
option casemap:none |
||
Line 2,326: | Line 2,326: | ||
ret |
ret |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
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. |
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}} |
{{out}} |
||
Line 2,340: | Line 2,340: | ||
=={{header|zkl}}== |
=={{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: |
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: |
||
< |
<syntaxhighlight lang=zkl>var BN=Import("zklBigNum"); |
||
BN(1)+2 //--> BN(3)</ |
BN(1)+2 //--> BN(3)</syntaxhighlight> |
||
and it "just works" as all objects are "the same" whether statically or dynamically linked. |
and it "just works" as all objects are "the same" whether statically or dynamically linked. |
||