Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
5
Task/Call-a-function-in-a-shared-library/00-META.yaml
Normal file
5
Task/Call-a-function-in-a-shared-library/00-META.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
category:
|
||||
- Functions and subroutines
|
||||
from: http://rosettacode.org/wiki/Call_a_function_in_a_shared_library
|
||||
note: Programming environment operations
|
||||
8
Task/Call-a-function-in-a-shared-library/00-TASK.txt
Normal file
8
Task/Call-a-function-in-a-shared-library/00-TASK.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
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.
|
||||
|
||||
This is a special case of [[Call foreign language function|calling a foreign language function]] where the focus is close to the [https://en.wikipedia.org/wiki/Application_binary_interface ABI] level and not at the normal API level.
|
||||
|
||||
|
||||
;Related task:
|
||||
* [[OpenGL]] -- OpenGL is usually maintained as a shared library.
|
||||
<br><br>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Interfaces; use Interfaces;
|
||||
with Interfaces.C; use Interfaces.C;
|
||||
with System; use System;
|
||||
|
||||
with Ada.Unchecked_Conversion;
|
||||
|
||||
procedure Shared_Library_Call is
|
||||
--
|
||||
-- Interface to kernel32.dll which is responsible for loading DLLs under Windows.
|
||||
-- There are ready to use Win32 bindings. We don't want to use them here.
|
||||
--
|
||||
type HANDLE is new Unsigned_32; -- on x64 system, replace by Unsigned_64 to make it work
|
||||
function LoadLibrary (lpFileName : char_array) return HANDLE;
|
||||
pragma Import (stdcall, LoadLibrary, "LoadLibrary", "_LoadLibraryA"); -- Ada95 does not have the @n suffix.
|
||||
|
||||
function GetProcAddress (hModule : HANDLE; lpProcName : char_array)
|
||||
return Address;
|
||||
pragma Import (stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress"); --
|
||||
--
|
||||
-- The interface of the function we want to call. It is a pointer (access type)
|
||||
-- because we will link it dynamically. The function is from User32.dll
|
||||
--
|
||||
type MessageBox is access function
|
||||
( hWnd : Address := Null_Address;
|
||||
lpText : char_array;
|
||||
lpCaption : char_array := To_C ("Greeting");
|
||||
uType : Unsigned_16 := 0
|
||||
) return Integer_16;
|
||||
pragma Convention (Stdcall, MessageBox);
|
||||
function To_MessageBox is new Ada.Unchecked_Conversion (Address, MessageBox);
|
||||
|
||||
Library : HANDLE := LoadLibrary (To_C ("user32.dll"));
|
||||
Pointer : Address := GetProcAddress (Library, To_C ("MessageBoxA"));
|
||||
begin
|
||||
if Pointer /= Null_Address then
|
||||
declare
|
||||
Result : Integer_16;
|
||||
begin
|
||||
Result := To_MessageBox (Pointer) (lpText => To_C ("Hello!"));
|
||||
end;
|
||||
else
|
||||
Put_Line ("Unable to load the library " & HANDLE'Image (Library));
|
||||
end if;
|
||||
end Shared_Library_Call;
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
with Ada.Environment_Variables; use Ada.Environment_Variables;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Interfaces; use Interfaces;
|
||||
with Interfaces.C; use Interfaces.C;
|
||||
with System; use System;
|
||||
|
||||
with Ada.Unchecked_Conversion;
|
||||
|
||||
procedure Shared_Library_Call is
|
||||
--
|
||||
-- Interface to libdl to load dynamically linked libraries
|
||||
--
|
||||
function dlopen (FileName : char_array; Flag : int) return Address;
|
||||
pragma Import (C, dlopen);
|
||||
|
||||
function dlsym (Handle : address; Symbol : char_array) return Address;
|
||||
pragma Import (C, dlsym);
|
||||
--
|
||||
-- The interfaces of the functions we want to call. These are pointers
|
||||
-- (access type) because we will link it dynamically. The functions
|
||||
-- come from libX11.so.
|
||||
--
|
||||
type XOpenDisplay is access function (Display_Name : char_array) return Address;
|
||||
pragma Convention (C, XOpenDisplay);
|
||||
function To_Ptr is new Ada.Unchecked_Conversion (Address, XOpenDisplay);
|
||||
|
||||
type XDisplayWidth is access function (Display : Address; Screen : int) return int;
|
||||
pragma Convention (C, XDisplayWidth);
|
||||
function To_Ptr is new Ada.Unchecked_Conversion (Address, XDisplayWidth);
|
||||
|
||||
Library : Address := dlopen (To_C ("libX11.so"), 1);
|
||||
OpenDisplay : XOpenDisplay := To_Ptr (dlsym (Library, To_C ("XOpenDisplay")));
|
||||
DisplayWidth : XDisplayWidth := To_Ptr (dlsym (Library, To_C ("XDisplayWidth")));
|
||||
begin
|
||||
if OpenDisplay /= null and then DisplayWidth /= null then
|
||||
declare
|
||||
Display : Address;
|
||||
begin
|
||||
Display := OpenDisplay (To_C (Value ("DISPLAY")));
|
||||
if Display = Null_Address then
|
||||
Put_Line ("Unable to open display " & Value ("DISPLAY"));
|
||||
else
|
||||
Put_Line (Value ("DISPLAY") & " width is" & int'image (DisplayWidth (Display, 0)));
|
||||
end if;
|
||||
end;
|
||||
else
|
||||
Put_Line ("Unable to load the library");
|
||||
end if;
|
||||
end Shared_Library_Call;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
getCurlVersion: function [][
|
||||
try? [
|
||||
call.external:'curl "curl_version" .expect: :string []
|
||||
]
|
||||
else [
|
||||
"library not found"
|
||||
]
|
||||
]
|
||||
|
||||
print ["curl version:" getCurlVersion]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ahkdll := DllCall("LoadLibrary", "str", "AutoHotkey.dll")
|
||||
clientHandle := DllCall("AutoHotkey\ahkdll", "str", "dllclient.ahk", "str"
|
||||
, "", "str", "parameter1 parameter2", "Cdecl Int")
|
||||
|
|
@ -0,0 +1 @@
|
|||
Msgbox, hello from client
|
||||
|
|
@ -0,0 +1 @@
|
|||
SYS "MessageBox", @hwnd%, "This is a test message", 0, 0
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
' Call a dynamic library function
|
||||
PROTO j0
|
||||
bessel0 = j0(1.0)
|
||||
PRINT bessel0
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#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++;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
identification division.
|
||||
program-id. callsym.
|
||||
|
||||
data division.
|
||||
working-storage section.
|
||||
01 handle usage pointer.
|
||||
01 addr usage program-pointer.
|
||||
|
||||
procedure division.
|
||||
call "dlopen" using
|
||||
by reference null
|
||||
by value 1
|
||||
returning handle
|
||||
on exception
|
||||
display function exception-statement upon syserr
|
||||
goback
|
||||
end-call
|
||||
if handle equal null then
|
||||
display function module-id ": error getting dlopen handle"
|
||||
upon syserr
|
||||
goback
|
||||
end-if
|
||||
|
||||
call "dlsym" using
|
||||
by value handle
|
||||
by content z"perror"
|
||||
returning addr
|
||||
end-call
|
||||
if addr equal null then
|
||||
display function module-id ": error getting perror symbol"
|
||||
upon syserr
|
||||
else
|
||||
call addr returning omitted
|
||||
end-if
|
||||
|
||||
goback.
|
||||
end program callsym.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
CL-USER> (cffi:load-foreign-library "libX11.so")
|
||||
#<CFFI::FOREIGN-LIBRARY {1004F4ECC1}>
|
||||
CL-USER> (cffi:foreign-funcall "XOpenDisplay"
|
||||
:string #+sbcl (sb-posix:getenv "DISPLAY")
|
||||
#-sbcl ":0.0"
|
||||
:pointer)
|
||||
#.(SB-SYS:INT-SAP #X00650FD0)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
libm = LibC.dlopen("libm.so.6", LibC::RTLD_LAZY)
|
||||
sqrtptr = LibC.dlsym(libm, "sqrt") unless libm.null?
|
||||
|
||||
if sqrtptr
|
||||
sqrtproc = Proc(Float64, Float64).new sqrtptr, Pointer(Void).null
|
||||
at_exit { LibC.dlclose(libm) }
|
||||
else
|
||||
sqrtproc = ->Math.sqrt(Float64)
|
||||
end
|
||||
|
||||
puts "the sqrt of 4 is #{sqrtproc.call(4.0)}"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
pragma(lib, "user32.lib");
|
||||
|
||||
import std.stdio, std.c.windows.windows;
|
||||
|
||||
extern(Windows) UINT GetDoubleClickTime();
|
||||
|
||||
void main() {
|
||||
writeln(GetDoubleClickTime());
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
int add(int num1, int num2) {
|
||||
return num1 + num2;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import 'dart:ffi'
|
||||
show DynamicLibrary, NativeFunction, Int32;
|
||||
|
||||
main(){
|
||||
final lib = DynamicLibrary.open('add.dylib'); // Load library
|
||||
|
||||
final int Function(int num1,int num2) add = lib // Write Dart function binding
|
||||
.lookup<NativeFunction<Int32 Function( Int32, Int32 )>>('add') // Lookup function in library
|
||||
.asFunction(); // convert to Dart Function
|
||||
|
||||
print( add( 1, 2 ) );
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
procedure DoSomething; external 'MYLIB.DLL';
|
||||
|
|
@ -0,0 +1 @@
|
|||
procedure DoSomething; external 'MYLIB.DLL' delayed;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
var
|
||||
lLibraryHandle: THandle;
|
||||
lDoSomething: procedure; stdcall;
|
||||
begin
|
||||
lLibraryHandle := LoadLibrary('MYLIB.DLL');
|
||||
if lLibraryHandle >= 32 then { success }
|
||||
begin
|
||||
lDoSomething := GetProcAddress(lLibraryHandle, 'DoSomething');
|
||||
lDoSomething();
|
||||
FreeLibrary(lLibraryHandle);
|
||||
end;
|
||||
end;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
c-library math
|
||||
|
||||
s" m" add-lib
|
||||
\c #include <math.h>
|
||||
c-function gamma tgamma r -- r
|
||||
|
||||
end-c-library
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
double add_n(double* a, double* b)
|
||||
{
|
||||
return *a + *b;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
function add_nf(a,b) bind(c, name='add_nf')
|
||||
use, intrinsic :: iso_c_binding
|
||||
implicit none
|
||||
real(c_double), intent(in) :: a,b
|
||||
real(c_double) :: add_nf
|
||||
|
||||
add_nf = a + b
|
||||
end function add_nf
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
!-----------------------------------------------------------------------
|
||||
!module dll_module
|
||||
!-----------------------------------------------------------------------
|
||||
module dll_module
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
private ! all by default
|
||||
public :: os_type, dll_type, load_dll, free_dll, init_os_type, init_dll
|
||||
! general constants:
|
||||
! the number of bits in an address (32-bit or 64-bit).
|
||||
integer, parameter :: bits_in_addr = c_intptr_t*8
|
||||
! global error-level variables:
|
||||
integer, parameter :: errid_none = 0
|
||||
integer, parameter :: errid_info = 1
|
||||
integer, parameter :: errid_warn = 2
|
||||
integer, parameter :: errid_severe = 3
|
||||
integer, parameter :: errid_fatal = 4
|
||||
|
||||
integer :: os_id
|
||||
|
||||
type os_type
|
||||
character(10) :: endian
|
||||
character(len=:), allocatable :: newline
|
||||
character(len=:), allocatable :: os_desc
|
||||
character(1) :: pathsep
|
||||
character(1) :: swchar
|
||||
character(11) :: unfform
|
||||
end type os_type
|
||||
|
||||
type dll_type
|
||||
integer(c_intptr_t) :: fileaddr
|
||||
type(c_ptr) :: fileaddrx
|
||||
type(c_funptr) :: procaddr
|
||||
character(1024) :: filename
|
||||
character(1024) :: procname
|
||||
end type dll_type
|
||||
|
||||
! interface to linux API
|
||||
interface
|
||||
function dlopen(filename,mode) bind(c,name="dlopen")
|
||||
! void *dlopen(const char *filename, int mode);
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
type(c_ptr) :: dlopen
|
||||
character(c_char), intent(in) :: filename(*)
|
||||
integer(c_int), value :: mode
|
||||
end function
|
||||
|
||||
function dlsym(handle,name) bind(c,name="dlsym")
|
||||
! void *dlsym(void *handle, const char *name);
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
type(c_funptr) :: dlsym
|
||||
type(c_ptr), value :: handle
|
||||
character(c_char), intent(in) :: name(*)
|
||||
end function
|
||||
|
||||
function dlclose(handle) bind(c,name="dlclose")
|
||||
! int dlclose(void *handle);
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
integer(c_int) :: dlclose
|
||||
type(c_ptr), value :: handle
|
||||
end function
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
|
||||
!-----------------------------------------------------------------------
|
||||
!Subroutine init_dll
|
||||
!-----------------------------------------------------------------------
|
||||
subroutine init_dll(dll)
|
||||
implicit none
|
||||
type(dll_type), intent(inout) :: dll
|
||||
dll % fileaddr = 0
|
||||
dll % fileaddrx = c_null_ptr
|
||||
dll % procaddr = c_null_funptr
|
||||
dll % filename = " "
|
||||
dll % procname = " "
|
||||
end subroutine init_dll
|
||||
|
||||
!-----------------------------------------------------------------------
|
||||
!Subroutine init_os_type
|
||||
!-----------------------------------------------------------------------
|
||||
subroutine init_os_type(os_id,os)
|
||||
implicit none
|
||||
integer, intent(in) :: os_id
|
||||
type(os_type), intent(inout) :: os
|
||||
|
||||
select case (os_id)
|
||||
case (1) ! Linux
|
||||
|
||||
os % endian = 'big_endian'
|
||||
os % newline = achar(10)
|
||||
os % os_desc = 'Linux'
|
||||
os % pathsep = '/'
|
||||
os % swchar = '-'
|
||||
os % unfform = 'unformatted'
|
||||
|
||||
case (2) ! MacOS
|
||||
|
||||
os % endian = 'big_endian'
|
||||
os % newline = achar(10)
|
||||
os % os_desc = 'MacOS'
|
||||
os % pathsep = '/'
|
||||
os % swchar = '-'
|
||||
os % unfform = 'unformatted'
|
||||
|
||||
case default
|
||||
|
||||
end select
|
||||
|
||||
end subroutine init_os_type
|
||||
|
||||
!-----------------------------------------------------------------------
|
||||
!Subroutine load_dll
|
||||
!-----------------------------------------------------------------------
|
||||
subroutine load_dll (os, dll, errstat, errmsg )
|
||||
! this subroutine is used to dynamically load a dll.
|
||||
|
||||
|
||||
type (os_type), intent(in) :: os
|
||||
type (dll_type), intent(inout) :: dll
|
||||
integer, intent( out) :: errstat
|
||||
character(*), intent( out) :: errmsg
|
||||
|
||||
integer(c_int), parameter :: rtld_lazy=1
|
||||
integer(c_int), parameter :: rtld_now=2
|
||||
integer(c_int), parameter :: rtld_global=256
|
||||
integer(c_int), parameter :: rtld_local=0
|
||||
|
||||
errstat = errid_none
|
||||
errmsg = ''
|
||||
|
||||
select case (os%os_desc)
|
||||
case ("Linux","MacOS")
|
||||
! load the dll and get the file address:
|
||||
dll%fileaddrx = dlopen( trim(dll%filename)//c_null_char, rtld_lazy )
|
||||
if( .not. c_associated(dll%fileaddrx) ) then
|
||||
errstat = errid_fatal
|
||||
write(errmsg,'(i2)') bits_in_addr
|
||||
errmsg = 'the dynamic library '//trim(dll%filename)//' could not be loaded. check that the file '// &
|
||||
'exists in the specified location and that it is compiled for '//trim(errmsg)//'-bit systems.'
|
||||
return
|
||||
end if
|
||||
|
||||
! get the procedure address:
|
||||
dll%procaddr = dlsym( dll%fileaddrx, trim(dll%procname)//c_null_char )
|
||||
if(.not. c_associated(dll%procaddr)) then
|
||||
errstat = errid_fatal
|
||||
errmsg = 'the procedure '//trim(dll%procname)//' in file '//trim(dll%filename)//' could not be loaded.'
|
||||
return
|
||||
end if
|
||||
|
||||
case ("Windows")
|
||||
errstat = errid_fatal
|
||||
errmsg = ' load_dll not implemented for '//trim(os%os_desc)
|
||||
|
||||
case default
|
||||
errstat = errid_fatal
|
||||
errmsg = ' load_dll not implemented for '//trim(os%os_desc)
|
||||
end select
|
||||
return
|
||||
end subroutine load_dll
|
||||
|
||||
!-----------------------------------------------------------------------
|
||||
!Subroutine free_dll
|
||||
!-----------------------------------------------------------------------
|
||||
subroutine free_dll (os, dll, errstat, errmsg )
|
||||
|
||||
! this subroutine is used to free a dynamically loaded dll
|
||||
type (os_type), intent(in) :: os
|
||||
type (dll_type), intent(inout) :: dll
|
||||
integer, intent( out) :: errstat
|
||||
character(*), intent( out) :: errmsg
|
||||
|
||||
integer(c_int) :: success
|
||||
|
||||
errstat = errid_none
|
||||
errmsg = ''
|
||||
|
||||
select case (os%os_desc)
|
||||
case ("Linux","MacOS")
|
||||
|
||||
! close the library:
|
||||
success = dlclose( dll%fileaddrx )
|
||||
if ( success /= 0 ) then
|
||||
errstat = errid_fatal
|
||||
errmsg = 'the dynamic library could not be freed.'
|
||||
return
|
||||
else
|
||||
errstat = errid_none
|
||||
errmsg = ''
|
||||
end if
|
||||
|
||||
case ("Windows")
|
||||
|
||||
errstat = errid_fatal
|
||||
errmsg = ' free_dll not implemented for '//trim(os%os_desc)
|
||||
|
||||
case default
|
||||
errstat = errid_fatal
|
||||
errmsg = ' free_dll not implemented for '//trim(os%os_desc)
|
||||
end select
|
||||
|
||||
return
|
||||
end subroutine free_dll
|
||||
end module dll_module
|
||||
|
||||
|
||||
|
||||
!-----------------------------------------------------------------------
|
||||
!Main program
|
||||
!-----------------------------------------------------------------------
|
||||
program test_load_dll
|
||||
use, intrinsic :: iso_c_binding
|
||||
use dll_module
|
||||
implicit none
|
||||
|
||||
! interface to our shared lib
|
||||
abstract interface
|
||||
function add_n(a,b)
|
||||
use, intrinsic :: iso_c_binding
|
||||
implicit none
|
||||
real(c_double), intent(in) :: a,b
|
||||
real(c_double) :: add_n
|
||||
end function add_n
|
||||
end interface
|
||||
|
||||
type(os_type) :: os
|
||||
type(dll_type) :: dll
|
||||
integer :: errstat
|
||||
character(1024) :: errmsg
|
||||
type(c_funptr) :: cfun
|
||||
procedure(add_n), pointer :: fproc
|
||||
|
||||
call init_os_type(1,os)
|
||||
call init_dll(dll)
|
||||
|
||||
dll%filename="/full_path_to/shared_lib/shared_lib_new.so"
|
||||
! name of the procedure in shared_lib
|
||||
! c version of the function
|
||||
dll%procname="add_n"
|
||||
|
||||
write(*,*) "address: ", dll%procaddr
|
||||
|
||||
call load_dll(os, dll, errstat, errmsg )
|
||||
write(*,*)"load_dll: errstat=", errstat
|
||||
write(*,*) "address: ", dll%procaddr
|
||||
|
||||
call c_f_procpointer(dll%procaddr,fproc)
|
||||
|
||||
write(*,*) "add_n(2,5)=",fproc(2.d0,5.d0)
|
||||
|
||||
call free_dll (os, dll, errstat, errmsg )
|
||||
write(*,*)"free_dll: errstat=", errstat
|
||||
|
||||
! fortran version
|
||||
dll%procname="add_nf"
|
||||
|
||||
call load_dll(os, dll, errstat, errmsg )
|
||||
write(*,*)"load_dll: errstat=", errstat
|
||||
write(*,*) "address: ", dll%procaddr
|
||||
|
||||
call c_f_procpointer(dll%procaddr,fproc)
|
||||
|
||||
write(*,*) "add_nf(2,5)=",fproc(2.d0,5.d0)
|
||||
|
||||
call free_dll (os, dll, errstat, errmsg )
|
||||
write(*,*)"free_dll: errstat=", errstat
|
||||
|
||||
|
||||
end program test_load_dll
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
function ffun(x, y)
|
||||
implicit none
|
||||
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: FFUN
|
||||
double precision :: x, y, ffun
|
||||
ffun = x + y * y
|
||||
end function
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
program dynload
|
||||
use kernel32
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
|
||||
abstract interface
|
||||
function ffun_int(x, y)
|
||||
!DEC$ ATTRIBUTES STDCALL, REFERENCE :: ffun_int
|
||||
double precision :: ffun_int, x, y
|
||||
end function
|
||||
end interface
|
||||
|
||||
procedure(ffun_int), pointer :: ffun_ptr
|
||||
|
||||
integer(c_intptr_t) :: ptr
|
||||
integer(handle) :: h
|
||||
double precision :: x, y
|
||||
|
||||
h = LoadLibrary("dllfun.dll" // c_null_char)
|
||||
if (h == 0) error stop "Error: LoadLibrary"
|
||||
|
||||
ptr = GetProcAddress(h, "ffun" // c_null_char)
|
||||
if (ptr == 0) error stop "Error: GetProcAddress"
|
||||
|
||||
call c_f_procpointer(transfer(ptr, c_null_funptr), ffun_ptr)
|
||||
read *, x, y
|
||||
print *, ffun_ptr(x, y)
|
||||
|
||||
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary"
|
||||
end program
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
function ffun(x, y)
|
||||
implicit none
|
||||
!GCC$ ATTRIBUTES DLLEXPORT, STDCALL :: FFUN
|
||||
double precision :: x, y, ffun
|
||||
ffun = x + y * y
|
||||
end function
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
program dynload
|
||||
use kernel32
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
|
||||
abstract interface
|
||||
function ffun_int(x, y)
|
||||
!GCC$ ATTRIBUTES DLLEXPORT, STDCALL :: FFUN
|
||||
double precision :: ffun_int, x, y
|
||||
end function
|
||||
end interface
|
||||
|
||||
procedure(ffun_int), pointer :: ffun_ptr
|
||||
|
||||
integer(c_intptr_t) :: ptr
|
||||
integer(handle) :: h
|
||||
double precision :: x, y
|
||||
|
||||
h = LoadLibrary("dllfun.dll" // c_null_char)
|
||||
if (h == 0) error stop "Error: LoadLibrary"
|
||||
|
||||
ptr = GetProcAddress(h, "ffun_@8" // c_null_char)
|
||||
if (ptr == 0) error stop "Error: GetProcAddress"
|
||||
|
||||
call c_f_procpointer(transfer(ptr, c_null_funptr), ffun_ptr)
|
||||
read *, x, y
|
||||
print *, ffun_ptr(x, y)
|
||||
|
||||
if (FreeLibrary(h) == 0) error stop "Error: FreeLibrary"
|
||||
end program
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
module kernel32
|
||||
use iso_c_binding
|
||||
implicit none
|
||||
integer, parameter :: HANDLE = C_INTPTR_T
|
||||
integer, parameter :: PVOID = C_INTPTR_T
|
||||
integer, parameter :: BOOL = C_INT
|
||||
|
||||
interface
|
||||
function LoadLibrary(lpFileName) bind(C, name="LoadLibraryA")
|
||||
import C_CHAR, HANDLE
|
||||
!GCC$ ATTRIBUTES STDCALL :: LoadLibrary
|
||||
integer(HANDLE) :: LoadLibrary
|
||||
character(C_CHAR) :: lpFileName
|
||||
end function
|
||||
end interface
|
||||
|
||||
interface
|
||||
function FreeLibrary(hModule) bind(C, name="FreeLibrary")
|
||||
import HANDLE, BOOL
|
||||
!GCC$ ATTRIBUTES STDCALL :: FreeLibrary
|
||||
integer(BOOL) :: FreeLibrary
|
||||
integer(HANDLE), value :: hModule
|
||||
end function
|
||||
end interface
|
||||
|
||||
interface
|
||||
function GetProcAddress(hModule, lpProcName) bind(C, name="GetProcAddress")
|
||||
import C_CHAR, PVOID, HANDLE
|
||||
!GCC$ ATTRIBUTES STDCALL :: GetProcAddress
|
||||
integer(PVOID) :: GetProcAddress
|
||||
integer(HANDLE), value :: hModule
|
||||
character(C_CHAR) :: lpProcName
|
||||
end function
|
||||
end interface
|
||||
end module
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
' Attempt to call Beep function in Win32 API
|
||||
Dim As Any Ptr library = DyLibLoad("kernel32.dll") '' load dll
|
||||
|
||||
If library = 0 Then
|
||||
Print "Unable to load kernel32.dll - calling built in Beep function instead"
|
||||
Beep : Beep : Beep
|
||||
Else
|
||||
Dim beep_ As Function (ByVal As ULong, ByVal As ULong) As Long '' declare function pointer
|
||||
beep_ = DyLibSymbol(library, "Beep")
|
||||
If beep_ = 0 Then
|
||||
Print "Unable to retrieve Beep function from kernel32.dll - calling built in Beep function instead"
|
||||
Beep : Beep : Beep
|
||||
Else
|
||||
For i As Integer = 1 To 3 : beep_(1000, 250) : Next
|
||||
End If
|
||||
DyLibFree(library) '' unload library
|
||||
End If
|
||||
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
include "tlbx GameplayKit.incl"
|
||||
|
||||
UInt64 randomInteger
|
||||
NSUInteger i
|
||||
|
||||
for i = 1 to 20
|
||||
randomInteger = fn GKLinearCongruentialRandomSourceSeed( fn GKLinearCongruentialRandomSourceInit )
|
||||
print randomInteger
|
||||
next
|
||||
|
||||
HandleEvents
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */
|
||||
int openimage(const char *s)
|
||||
{
|
||||
static int handle = 100;
|
||||
fprintf(stderr, "opening %s\n", s);
|
||||
return handle++;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -ldl
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef int (*someFunc) (const char *s);
|
||||
|
||||
int bridge_someFunc(someFunc f, const char *s) {
|
||||
return f(s);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var handle = -1
|
||||
|
||||
func myOpenImage(s string) int {
|
||||
fmt.Fprintf(os.Stderr, "internal openImage opens %s...\n", s)
|
||||
handle++
|
||||
return handle
|
||||
}
|
||||
|
||||
func main() {
|
||||
libpath := C.CString("./fakeimglib.so")
|
||||
defer C.free(unsafe.Pointer(libpath))
|
||||
imglib := C.dlopen(libpath, C.RTLD_LAZY)
|
||||
var imghandle int
|
||||
if imglib != nil {
|
||||
openimage := C.CString("openimage")
|
||||
defer C.free(unsafe.Pointer(openimage))
|
||||
fp := C.dlsym(imglib, openimage)
|
||||
if fp != nil {
|
||||
fi := C.CString("fake.img")
|
||||
defer C.free(unsafe.Pointer(fi))
|
||||
imghandle = int(C.bridge_someFunc(C.someFunc(fp), fi))
|
||||
|
||||
} else {
|
||||
imghandle = myOpenImage("fake.img")
|
||||
}
|
||||
C.dlclose(imglib)
|
||||
} else {
|
||||
imghandle = myOpenImage("fake.img")
|
||||
}
|
||||
fmt.Printf("opened with handle %d\n", imghandle)
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env stack
|
||||
-- stack --resolver lts-6.33 --install-ghc runghc --package unix
|
||||
|
||||
import Control.Exception ( try )
|
||||
import Foreign ( FunPtr, allocaBytes )
|
||||
import Foreign.C
|
||||
( CSize(..), CString, withCAStringLen, peekCAStringLen )
|
||||
import System.Info ( os )
|
||||
import System.IO.Error ( ioeGetErrorString )
|
||||
import System.IO.Unsafe ( unsafePerformIO )
|
||||
import System.Posix.DynamicLinker
|
||||
( RTLDFlags(RTLD_LAZY), dlsym, dlopen )
|
||||
|
||||
dlSuffix :: String
|
||||
dlSuffix = if os == "darwin" then ".dylib" else ".so"
|
||||
|
||||
type RevFun = CString -> CString -> CSize -> IO ()
|
||||
|
||||
foreign import ccall "dynamic"
|
||||
mkFun :: FunPtr RevFun -> RevFun
|
||||
|
||||
callRevFun :: RevFun -> String -> String
|
||||
callRevFun f s = unsafePerformIO $ withCAStringLen s $ \(cs, len) -> do
|
||||
allocaBytes len $ \buf -> do
|
||||
f buf cs (fromIntegral len)
|
||||
peekCAStringLen (buf, len)
|
||||
|
||||
getReverse :: IO (String -> String)
|
||||
getReverse = do
|
||||
lib <- dlopen ("libcrypto" ++ dlSuffix) [RTLD_LAZY]
|
||||
fun <- dlsym lib "BUF_reverse"
|
||||
return $ callRevFun $ mkFun fun
|
||||
|
||||
main = do
|
||||
x <- try getReverse
|
||||
let (msg, rev) =
|
||||
case x of
|
||||
Left e -> (ioeGetErrorString e ++ "; using fallback", reverse)
|
||||
Right f -> ("Using BUF_reverse from OpenSSL", f)
|
||||
putStrLn msg
|
||||
putStrLn $ rev "a man a plan a canal panama"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
require 'dll'
|
||||
strdup=: 'msvcrt.dll _strdup >x *' cd <
|
||||
free=: 'msvcrt.dll free n x' cd <
|
||||
getstr=: free ] memr@,&0 _1
|
||||
|
||||
DupStr=:verb define
|
||||
try.
|
||||
getstr@strdup y
|
||||
catch.
|
||||
y
|
||||
end.
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
DupStr 'hello'
|
||||
hello
|
||||
getstr@strdup ::] 'hello'
|
||||
hello
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* TrySort.java */
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
public class TrySort {
|
||||
static boolean useC;
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("TrySort");
|
||||
useC = true;
|
||||
} catch(UnsatisfiedLinkError e) {
|
||||
useC = false;
|
||||
}
|
||||
}
|
||||
|
||||
static native void sortInC(int[] ary);
|
||||
|
||||
static class IntList extends java.util.AbstractList<Integer> {
|
||||
int[] ary;
|
||||
IntList(int[] ary) { this.ary = ary; }
|
||||
public Integer get(int i) { return ary[i]; }
|
||||
public Integer set(int i, Integer j) {
|
||||
Integer o = ary[i]; ary[i] = j; return o;
|
||||
}
|
||||
public int size() { return ary.length; }
|
||||
}
|
||||
|
||||
static class ReverseAbsCmp
|
||||
implements java.util.Comparator<Integer>
|
||||
{
|
||||
public int compare(Integer pa, Integer pb) {
|
||||
/* Order from highest to lowest absolute value. */
|
||||
int a = pa > 0 ? -pa : pa;
|
||||
int b = pb > 0 ? -pb : pb;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void sortInJava(int[] ary) {
|
||||
Collections.sort(new IntList(ary), new ReverseAbsCmp());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/* Create an array of random integers. */
|
||||
int[] ary = new int[1000000];
|
||||
Random rng = new Random();
|
||||
for (int i = 0; i < ary.length; i++)
|
||||
ary[i] = rng.nextInt();
|
||||
|
||||
/* Do the reverse sort. */
|
||||
if (useC) {
|
||||
System.out.print("Sorting in C... ");
|
||||
sortInC(ary);
|
||||
} else {
|
||||
System.out.print
|
||||
("Missing library for C! Sorting in Java... ");
|
||||
sortInJava(ary);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ary.length - 1; i++) {
|
||||
int a = ary[i];
|
||||
int b = ary[i + 1];
|
||||
if ((a > 0 ? -a : a) > (b > 0 ? -b : b)) {
|
||||
System.out.println("*BUG IN SORT*");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
System.out.println("ok");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/* TrySort.c */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "TrySort.h"
|
||||
|
||||
static void fail(JNIEnv *jenv, const char *error_name) {
|
||||
jclass error_class = (*jenv)->FindClass(jenv, error_name);
|
||||
(*jenv)->ThrowNew(jenv, error_class, NULL);
|
||||
}
|
||||
|
||||
static int reverse_abs_cmp(const void *pa, const void *pb) {
|
||||
jint a = *(jint *)pa;
|
||||
jint b = *(jint *)pb;
|
||||
a = a > 0 ? -a : a;
|
||||
b = b > 0 ? -b : b;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
|
||||
void Java_TrySort_sortInC(JNIEnv *jenv, jclass obj, jintArray ary) {
|
||||
jint *elem, length;
|
||||
|
||||
if (ary == NULL) {
|
||||
fail(jenv, "java/lang/NullPointerException");
|
||||
return;
|
||||
}
|
||||
length = (*jenv)->GetArrayLength(jenv, ary);
|
||||
elem = (*jenv)->GetPrimitiveArrayCritical(jenv, ary, NULL);
|
||||
if (elem == NULL) {
|
||||
fail(jenv, "java/lang/OutOfMemoryError");
|
||||
return;
|
||||
}
|
||||
qsort(elem, length, sizeof(jint), reverse_abs_cmp);
|
||||
(*jenv)->ReleasePrimitiveArrayCritical(jenv, ary, elem, 0);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Makefile
|
||||
|
||||
# Edit the next lines to match your JDK.
|
||||
JAVA_HOME = /usr/local/jdk-1.8.0
|
||||
CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/openbsd
|
||||
JAVAC = $(JAVA_HOME)/bin/javac
|
||||
JAVAH = $(JAVA_HOME)/bin/javah
|
||||
|
||||
CC = cc
|
||||
LDFLAGS = -shared -fPIC
|
||||
LIB = libTrySort.so
|
||||
|
||||
all: TrySort.class $(LIB)
|
||||
|
||||
$(LIB): TrySort.c TrySort.h
|
||||
$(CC) $(CPPFLAGS) $(LDFLAGS) -o $@ TrySort.c
|
||||
|
||||
.SUFFIXES: .class .java .h
|
||||
.class.h:
|
||||
rm -f $@
|
||||
$(JAVAH) -jni -o $@ $(<:.class=)
|
||||
.java.class:
|
||||
$(JAVAC) $<
|
||||
|
||||
clean:
|
||||
rm -f TrySort.class TrySort?IntList.class \
|
||||
TrySort?ReverseAbsCmp.class TrySort.h $(LIB)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
public class LoadLibJNA{
|
||||
private interface YourSharedLibraryName extends Library{
|
||||
//put shared library functions here with no definition
|
||||
public void sharedLibraryfunction();
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
YourSharedLibraryName lib = (YourSharedLibraryName)Native.loadLibrary("sharedLibrary",//as in "sharedLibrary.dll"
|
||||
YourSharedLibraryName.class);
|
||||
lib.sharedLibraryFunction();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/local/bin/jsish
|
||||
load('byjsi.so');
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
identification division.
|
||||
program-id. sample as "Jsi_Initbyjsi".
|
||||
|
||||
environment division.
|
||||
configuration section.
|
||||
special-names.
|
||||
call-convention 0 is extern.
|
||||
repository.
|
||||
function all intrinsic.
|
||||
|
||||
data division.
|
||||
linkage section.
|
||||
01 jsi-interp usage pointer.
|
||||
01 rel usage binary-long.
|
||||
|
||||
procedure division using by value jsi-interp rel.
|
||||
sample-main.
|
||||
if rel equal zero then
|
||||
display "GnuCOBOL from jsish load of " module-source()
|
||||
" and cobc -m -fimplicit-init" upon syserr
|
||||
goback
|
||||
end-if
|
||||
|
||||
display "Called again with: " jsi-interp ", " rel upon syserr
|
||||
goback.
|
||||
end program sample.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#this example works on Windows
|
||||
ccall( (:GetDoubleClickTime, "User32"), stdcall,
|
||||
Uint, (), )
|
||||
|
||||
ccall( (:clock, "libc"), Int32, ())
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
/* gcc -shared -fPIC -nostartfiles fakeimglib.c -o fakeimglib.so */
|
||||
int openimage(const char *s)
|
||||
{
|
||||
static int handle = 100;
|
||||
fprintf(stderr, "opening %s\n", s);
|
||||
return handle++;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// Kotlin Native version 0.5
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import platform.posix.*
|
||||
import platform.linux.*
|
||||
|
||||
typealias Func = (String)-> Int
|
||||
|
||||
var handle = 0
|
||||
|
||||
fun myOpenImage(s: String): Int {
|
||||
fprintf(stderr, "internal openImage opens %s...\n", s)
|
||||
return handle++
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
var imgHandle: Int
|
||||
val imglib = dlopen("./fakeimglib.so", RTLD_LAZY)
|
||||
if (imglib != null) {
|
||||
val fp = dlsym(imglib, "openimage")
|
||||
if (fp != null) {
|
||||
val extOpenImage: CPointer<CFunction<Func>> = fp.reinterpret()
|
||||
imgHandle = extOpenImage("fake.img")
|
||||
}
|
||||
else {
|
||||
imgHandle = myOpenImage("fake.img")
|
||||
}
|
||||
dlclose(imglib)
|
||||
}
|
||||
else {
|
||||
imgHandle = myOpenImage("fake.img")
|
||||
}
|
||||
println("opened with handle $imgHandle")
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{script
|
||||
LAMBDATALK.DICT['BN.*'] = function(){
|
||||
var args = arguments[0].split(' '),
|
||||
a = new BigNumber( args[0], BN_DEC ),
|
||||
b = new BigNumber( args[1], BN_DEC );
|
||||
return a.multiply( b )
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{BN.* 123456789123456789123456789 123456789123456789123456789}
|
||||
-> 15241578780673678546105778281054720515622620750190521
|
||||
|
||||
to be compared with the "standard" lambdatalk builtin * operator
|
||||
|
||||
{* 123456789123456789123456789 123456789123456789123456789}
|
||||
-> 1.524157878067368e+52
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
-- calculate CRC-32 checksum
|
||||
str = "The quick brown fox jumps over the lazy dog"
|
||||
|
||||
-- is shared library (in Director called "Xtra", a DLL in windows, a sharedLib in
|
||||
-- OS X) available?
|
||||
if ilk(xtra("Crypto"))=#xtra then
|
||||
|
||||
-- use shared library
|
||||
cx = xtra("Crypto").new()
|
||||
crc = cx.cx_crc32_string(str)
|
||||
|
||||
else
|
||||
|
||||
-- otherwise use (slower) pure lingo solution
|
||||
crcObj = script("CRC").new()
|
||||
crc = crcObj.crc32(str)
|
||||
|
||||
end if
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
alien = require("alien")
|
||||
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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
> cfloor := define_external( floor, s::float[8], RETURN::float[8], LIB = "libm.so" ):
|
||||
> cfloor( 2.3 );
|
||||
2.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
Needs["NETLink`"];
|
||||
externalFloor = DefineDLLFunction["floor", "msvcrt.dll", "double", { "double" }];
|
||||
externalFloor[4.2]
|
||||
-> 4.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
proc openimage(s: cstring): cint {.importc, dynlib: "./fakeimglib.so".}
|
||||
|
||||
echo openimage("foo")
|
||||
echo openimage("bar")
|
||||
echo openimage("baz")
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#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++;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
proc openimage(s: string): int {.importc, dynlib: "./libfakeimg.so".}
|
||||
|
||||
echo openimage("foo")
|
||||
echo openimage("bar")
|
||||
echo openimage("baz")
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# nim c --app:lib fakeimg.nim
|
||||
var handle = 100
|
||||
|
||||
proc openimage*(s: string): int {.exportc, dynlib.} =
|
||||
stderr.writeln "opening ", s
|
||||
result = handle
|
||||
inc(handle)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
open Dlffi
|
||||
|
||||
let get_int = function Int v -> v | _ -> failwith "get_int"
|
||||
let get_ptr = function Ptr v -> v | _ -> failwith "get_ptr"
|
||||
let get_float = function Float v -> v | _ -> failwith "get_float"
|
||||
let get_double = function Double v -> v | _ -> failwith "get_double"
|
||||
let get_string = function String v -> v | _ -> failwith "get_string"
|
||||
|
||||
let () =
|
||||
(* load the library *)
|
||||
let xlib = dlopen "/usr/lib/libX11.so" [RTLD_LAZY] in
|
||||
(* load the functions *)
|
||||
let _open_display = dlsym xlib "XOpenDisplay"
|
||||
and _default_screen = dlsym xlib "XDefaultScreen"
|
||||
and _display_width = dlsym xlib "XDisplayWidth"
|
||||
and _display_height = dlsym xlib "XDisplayHeight"
|
||||
in
|
||||
(* wrap functions to provide a higher level interface *)
|
||||
let open_display ~name = get_ptr(fficall _open_display [| String name |] Return_ptr)
|
||||
and default_screen ~dpy = get_int(fficall _default_screen [| (Ptr dpy) |] Return_int)
|
||||
and display_width ~dpy ~scr = get_int(fficall _display_width [| (Ptr dpy); (Int scr) |] Return_int)
|
||||
and display_height ~dpy ~scr = get_int(fficall _display_height [| (Ptr dpy); (Int scr) |] Return_int)
|
||||
in
|
||||
(* use our functions *)
|
||||
let dpy = open_display ~name:":0" in
|
||||
let screen_number = default_screen ~dpy in
|
||||
let width = display_width ~dpy ~scr:screen_number
|
||||
and height = display_height ~dpy ~scr:screen_number in
|
||||
Printf.printf "# Screen dimensions are: %d x %d pixels\n" width height;
|
||||
dlclose xlib;
|
||||
;;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(import (otus ffi))
|
||||
|
||||
(define self (load-dynamic-library #f))
|
||||
(define strdup
|
||||
(self type-string "strdup" type-string))
|
||||
|
||||
(print (strdup "Hello World!"))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
(import (otus ffi))
|
||||
|
||||
(define self (load-dynamic-library #f))
|
||||
(define strdup
|
||||
(let ((strdup (self type-vptr "strdup" type-string))
|
||||
(free (self fft-void "free" type-vptr)))
|
||||
(lambda (str)
|
||||
(let*((dupped (strdup str))
|
||||
(result (vptr->string dupped)))
|
||||
(free dupped)
|
||||
result))))
|
||||
|
||||
(print (strdup "Hello World!"))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
'Loading a shared library at run time and calling a function.
|
||||
|
||||
declare MessageBox(sys hWnd, String text,caption, sys utype)
|
||||
|
||||
sys user32 = LoadLibrary "user32.dll"
|
||||
|
||||
if user32 then @Messagebox = getProcAddress user32,"MessageBoxA"
|
||||
|
||||
if @MessageBox then MessageBox 0,"Hello","OxygenBasic",0
|
||||
|
||||
'...
|
||||
|
||||
FreeLibrary user32
|
||||
|
|
@ -0,0 +1 @@
|
|||
install("function_name","G","gp_name","./test.gp.so");
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
use Inline
|
||||
C => "DATA",
|
||||
ENABLE => "AUTOWRAP",
|
||||
LIBS => "-lm";
|
||||
|
||||
print 4*atan(1) . "\n";
|
||||
|
||||
__DATA__
|
||||
__C__
|
||||
double atan(double x);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
use FFI::Platypus;
|
||||
my $ffi = FFI::Platypus->new;
|
||||
$ffi->lib(undef);
|
||||
$ffi->attach(puts => ['string'] => 'int');
|
||||
$ffi->attach(atan => ['double'] => 'double');
|
||||
|
||||
puts(4*atan(1));
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(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: #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;">atom</span> <span style="color: #000000;">lib</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">open_dll</span><span style="color: #0000FF;">(</span><span style="color: #000000;">libname</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">func</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lib</span><span style="color: #0000FF;">,</span><span style="color: #000000;">funcname</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">},</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">func</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">?{{</span><span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">)}}</span> <span style="color: #000080;font-style:italic;">-- (you don't //have// to crash!)</span>
|
||||
<span style="color: #008080;">else</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>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
(load "@lib/gcc.l")
|
||||
|
||||
(gcc "x11" '("-lX11") 'xOpenDisplay 'xCloseDisplay)
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
any xOpenDisplay(any ex) {
|
||||
any x = evSym(cdr(ex)); // Get display name
|
||||
char display[bufSize(x)]; // Create a buffer for the name
|
||||
|
||||
bufString(x, display); // Upack the name
|
||||
return boxCnt((long)XOpenDisplay(display));
|
||||
}
|
||||
|
||||
any xCloseDisplay(any ex) {
|
||||
return boxCnt(XCloseDisplay((Display*)evCnt(ex, cdr(ex))));
|
||||
}
|
||||
/**/
|
||||
|
||||
# With that we can open and close the display:
|
||||
: (setq Display (xOpenDisplay ":0.7")) # Wrong
|
||||
-> 0
|
||||
: (setq Display (xOpenDisplay ":0.0")) # Correct
|
||||
-> 158094320
|
||||
: (xCloseDisplay Display)
|
||||
-> 0
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
: (setq Display (native "/usr/lib/libX11.so.6" "XOpenDisplay" 'N ":0.0"))
|
||||
-> 6502688
|
||||
: (native "/usr/lib/libX11.so.6" "XCloseDisplay" 'I Display)
|
||||
-> 0
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#INCLUDE "Win32API.inc"
|
||||
|
||||
FUNCTION PBMAIN () AS LONG
|
||||
DIM hWnd AS LONG
|
||||
DIM msg AS ASCIIZ * 14, titl AS ASCIIZ * 8
|
||||
|
||||
hWnd = LoadLibrary ("user32")
|
||||
msg = "Hello, world!"
|
||||
titl = "Example"
|
||||
IF ISTRUE (hWnd) THEN
|
||||
funcAddr& = GetProcAddress (hWnd, "MessageBoxA")
|
||||
IF ISTRUE (funcAddr&) THEN
|
||||
ASM push 0&
|
||||
tAdr& = VARPTR(titl)
|
||||
ASM push tAdr&
|
||||
mAdr& = VARPTR(msg)
|
||||
ASM push mAdr&
|
||||
ASM push 0&
|
||||
CALL DWORD funcAddr&
|
||||
ELSE
|
||||
GOTO epicFail
|
||||
END IF
|
||||
ELSE
|
||||
GOTO epicFail
|
||||
END IF
|
||||
|
||||
GOTO getMeOuttaHere
|
||||
|
||||
epicFail:
|
||||
MSGBOX msg, , titl
|
||||
|
||||
getMeOuttaHere:
|
||||
IF ISTRUE(hWnd) THEN
|
||||
tmp& = FreeLibrary (hWnd)
|
||||
IF ISFALSE(tmp&) THEN MSGBOX "Error freeing library... [shrug]"
|
||||
END IF
|
||||
END FUNCTION
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
if OpenLibrary(0, "USER32.DLL")
|
||||
*MessageBox = GetFunction(0, "MessageBoxA")
|
||||
CallFunctionFast(*MessageBox, 0, "Body", "Title", 0)
|
||||
CloseLibrary(0)
|
||||
endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Prototype.l ProtoMessageBoxW(Window.l, Body.p-unicode, Title.p-unicode, Flags.l = 0)
|
||||
|
||||
If OpenLibrary(0, "User32.dll")
|
||||
MsgBox.ProtoMessageBoxW = GetFunction(0, "MessageBoxW")
|
||||
MsgBox(0, "Hello", "World")
|
||||
CloseLibrary(0)
|
||||
EndIf
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import ctypes
|
||||
|
||||
user32_dll = ctypes.cdll.LoadLibrary('User32.dll')
|
||||
print user32_dll.GetDoubleClickTime()
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
>>> import ctypes
|
||||
>>> # libc = ctypes.cdll.msvcrt # Windows
|
||||
>>> # libc = ctypes.CDLL('libc.dylib') # Mac
|
||||
>>> libc = ctypes.CDLL('libc.so') # Linux and most other *nix
|
||||
>>> libc.printf(b'hi there, %s\n', b'world')
|
||||
hi there, world.
|
||||
17
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
>>> from cffi import FFI
|
||||
>>> ffi = FFI()
|
||||
>>> ffi.cdef("""
|
||||
... int printf(const char *format, ...); // copy-pasted from the man page
|
||||
... """)
|
||||
>>> C = ffi.dlopen(None) # loads the entire C namespace
|
||||
>>> arg = ffi.new("char[]", b"world") # equivalent to C code: char arg[] = "world";
|
||||
>>> C.printf(b"hi there, %s.\n", arg) # call printf
|
||||
hi there, world.
|
||||
17
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Declare Dynamic Library "Kernel32"
|
||||
Sub SetLastError (ByVal dwErr As Long)
|
||||
Function GetLastError& ()
|
||||
End Declare
|
||||
|
||||
SetLastError 20
|
||||
Print GetLastError
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
dyn.load("my/special/R/lib.so")
|
||||
.Call("my_lib_fun", arg1, arg2)
|
||||
|
|
@ -0,0 +1 @@
|
|||
.C("my_lib_fun", arg1, arg2, ret)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*REXX program calls a function (sysTextScreenSize) in a shared library (regUtil). */
|
||||
|
||||
/*Note: the REGUTIL.DLL (REGina UTILity Dynamic Link Library */
|
||||
/* should be in the PATH or the current directory. */
|
||||
|
||||
rca= rxFuncAdd('sysLoadFuncs', "regUtil", 'sysLoadFuncs') /*add a function library. */
|
||||
if rca\==0 then do /*examine the return code.*/
|
||||
say 'return code' rca "from rxFuncAdd" /*tell about bad " " */
|
||||
exit rca /*exit this program with RC. */
|
||||
end
|
||||
|
||||
rcl= sysLoadFuncs() /*we can load the functions. */
|
||||
if rcl\==0 then do /*examine the return code.*/
|
||||
say 'return code' rcl "from sysLoadFuncs" /*tell about bad " " */
|
||||
exit rcl /*exit this program with RC. */
|
||||
end
|
||||
/* [↓] call a function. */
|
||||
$= sysTextScreenSize() /*$ has 2 words: rows cols */
|
||||
parse var $ rows cols . /*get two numeric words in $.*/
|
||||
say ' rows=' rows /*show number of screen rows.*/
|
||||
say ' cols=' cols /* " " " " cols.*/
|
||||
|
||||
rcd= SysDropFuncs() /*make functions inaccessible*/
|
||||
if rcd\==0 then do /*examine the return code.*/
|
||||
say 'return code' rcd "from sysDropFuncs" /*tell about bad " " */
|
||||
exit rcd /*exit this program with RC. */
|
||||
end
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#lang 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)))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
use NativeCall;
|
||||
|
||||
sub XOpenDisplay(Str $s --> int64) is native('X11') {*}
|
||||
sub XCloseDisplay(int64 $i --> int32) is native('X11') {*}
|
||||
|
||||
if try my $d = XOpenDisplay ":0.0" {
|
||||
say "ID = $d";
|
||||
XCloseDisplay($d);
|
||||
}
|
||||
else {
|
||||
say "No X11 library!";
|
||||
say "Use this window instead --> ⬜";
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
require 'fiddle/import'
|
||||
|
||||
module FakeImgLib
|
||||
extend Fiddle::Importer
|
||||
begin
|
||||
dlload './fakeimglib.so'
|
||||
extern 'int openimage(const char *)'
|
||||
rescue Fiddle::DLError
|
||||
# Either fakeimglib or openimage() is missing.
|
||||
@@handle = -1
|
||||
def openimage(path)
|
||||
$stderr.puts "internal openimage opens #{path}\n"
|
||||
@@handle += 1
|
||||
end
|
||||
module_function :openimage
|
||||
end
|
||||
end
|
||||
|
||||
handle = FakeImgLib.openimage("path/to/image")
|
||||
puts "opened with handle #{handle}"
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# This script shows the width x height of some images.
|
||||
# Example:
|
||||
# $ ruby imsize.rb dwarf-vs-elf.png swedish-chef.jpg
|
||||
# dwarf-vs-elf.png: 242x176
|
||||
# swedish-chef.jpg: 256x256
|
||||
|
||||
begin
|
||||
require 'rmagick'
|
||||
lib = :rmagick
|
||||
rescue LoadError
|
||||
# Missing rmagick. Try ffi.
|
||||
begin
|
||||
require 'ffi'
|
||||
module F
|
||||
extend FFI::Library
|
||||
ffi_lib 'MagickWand-6.Q16'
|
||||
attach_function :DestroyMagickWand, [:pointer], :pointer
|
||||
attach_function :MagickGetImageHeight, [:pointer], :size_t
|
||||
attach_function :MagickGetImageWidth, [:pointer], :size_t
|
||||
attach_function :MagickPingImage, [:pointer, :string], :bool
|
||||
attach_function :MagickWandGenesis, [], :void
|
||||
attach_function :NewMagickWand, [], :pointer
|
||||
end
|
||||
lib = :ffi
|
||||
rescue LoadError
|
||||
# Missing ffi, MagickWand lib, or function in lib.
|
||||
end
|
||||
end
|
||||
|
||||
case lib
|
||||
when :rmagick
|
||||
# Returns [width, height] of an image file.
|
||||
def size(path)
|
||||
img = Magick::Image.ping(path).first
|
||||
[img.columns, img.rows]
|
||||
end
|
||||
when :ffi
|
||||
F.MagickWandGenesis()
|
||||
def size(path)
|
||||
wand = F.NewMagickWand()
|
||||
F.MagickPingImage(wand, path) or fail 'problem reading image'
|
||||
[F.MagickGetImageWidth(wand), F.MagickGetImageHeight(wand)]
|
||||
ensure
|
||||
F.DestroyMagickWand(wand) if wand
|
||||
end
|
||||
else
|
||||
PngSignature = "\x89PNG\r\n\x1A\n".force_encoding('binary')
|
||||
def size(path)
|
||||
File.open(path, 'rb') do |file|
|
||||
# Only works with PNG: https://www.w3.org/TR/PNG/
|
||||
# Reads [width, height] from IDHR chunk.
|
||||
# Checks height != nil, but doesn't check CRC of chunk.
|
||||
sig, width, height = file.read(24).unpack('a8@16NN')
|
||||
sig == PngSignature and height or fail 'not a PNG image'
|
||||
[width, height]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Show the size of each image in ARGV.
|
||||
status = true
|
||||
ARGV.empty? and (warn "usage: $0 file..."; exit false)
|
||||
ARGV.each do |path|
|
||||
begin
|
||||
r, c = size(path)
|
||||
puts "#{path}: #{r}x#{c}"
|
||||
rescue
|
||||
status = false
|
||||
puts "#{path}: #$!"
|
||||
end
|
||||
end
|
||||
exit status
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#![allow(unused_unsafe)]
|
||||
extern crate libc;
|
||||
|
||||
use std::io::{self,Write};
|
||||
use std::{mem,ffi,process};
|
||||
|
||||
use libc::{c_double, RTLD_NOW};
|
||||
|
||||
// Small macro which wraps turning a string-literal into a c-string.
|
||||
// This is always safe to call, and the resulting pointer has 'static lifetime
|
||||
macro_rules! to_cstr {
|
||||
($s:expr) => {unsafe {ffi::CStr::from_bytes_with_nul_unchecked(concat!($s, "\0").as_bytes()).as_ptr()}}
|
||||
}
|
||||
|
||||
macro_rules! from_cstr {
|
||||
($p:expr) => {ffi::CStr::from_ptr($p).to_string_lossy().as_ref() }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let handle = libc::dlopen(to_cstr!("libm.so.6"), RTLD_NOW);
|
||||
|
||||
if handle.is_null() {
|
||||
writeln!(&mut io::stderr(), "{}", from_cstr!(libc::dlerror())).unwrap();
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let extern_cos = libc::dlsym(handle, to_cstr!("cos"))
|
||||
.as_ref()
|
||||
.map(mem::transmute::<_,fn (c_double) -> c_double)
|
||||
.unwrap_or(builtin_cos);
|
||||
println!("{}", extern_cos(4.0));
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_cos(x: c_double) -> c_double {
|
||||
x.cos()
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
-INCLUDE 'ffi.sno'
|
||||
|
||||
ffi_m = FFI_DLOPEN('/usr/lib/x86_64-linux-gnu/libm.so')
|
||||
ffi_m_hypot = FFI_DLSYM(ffi_m, 'hypot')
|
||||
DEFINE_FFI('hypot(double,double)double', ffi_m_hypot)
|
||||
|
||||
OUTPUT = hypot(1,2)
|
||||
OUTPUT = hypot(2,3)
|
||||
OUTPUT = hypot(3,4)
|
||||
OUTPUT = hypot(4,5)
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import net.java.dev.sna.SNA
|
||||
import com.sun.jna.ptr.IntByReference
|
||||
|
||||
object GetDiskFreeSpace extends App with SNA {
|
||||
|
||||
snaLibrary = "Kernel32" // Native library name
|
||||
/*
|
||||
* Important Note!
|
||||
*
|
||||
* The val holding the SNA-returned function must have the same name as the native function itself
|
||||
* (see line following this comment). This is the only place you specify the native function name.
|
||||
*/
|
||||
val GetDiskFreeSpaceA = SNA[String, IntByReference, IntByReference, IntByReference, IntByReference, Boolean]
|
||||
|
||||
// This Windows function is described here:
|
||||
// http://msdn.microsoft.com/en-us/library/aa364935(v=vs.85).aspx
|
||||
val (disk, spc, bps, fc, tc) = ("C:\\",
|
||||
new IntByReference, // Sectors per cluster
|
||||
new IntByReference, // Bytes per sector
|
||||
new IntByReference, // Free clusters
|
||||
new IntByReference) // Total clusters
|
||||
|
||||
val ok = GetDiskFreeSpaceA(disk, spc, bps, fc, tc) // status
|
||||
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")
|
||||
}}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
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'.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
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"]
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#import std
|
||||
#import flo
|
||||
|
||||
my_replacement = fleq/0.?/~& negative
|
||||
|
||||
abs = math.|fabs my_replacement
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
function ffun(x, y)
|
||||
implicit none
|
||||
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: ffun
|
||||
double precision :: x, y, ffun
|
||||
ffun = x + y * y
|
||||
end function
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
Option Explicit
|
||||
Declare Function ffun Lib "vbafun" (ByRef x As Double, ByRef y As Double) As Double
|
||||
Sub Test()
|
||||
Dim x As Double, y As Double
|
||||
x = 2#
|
||||
y = 10#
|
||||
Debug.Print ffun(x, y)
|
||||
End Sub
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/* call_shared_library_function.wren */
|
||||
|
||||
var RTLD_LAZY = 1
|
||||
|
||||
foreign class DL {
|
||||
construct open(file, mode) {}
|
||||
|
||||
foreign call(symbol, arg)
|
||||
|
||||
foreign close()
|
||||
}
|
||||
|
||||
class My {
|
||||
static openimage(s) {
|
||||
System.print("internal openimage opens %(s)...")
|
||||
if (!__handle) __handle = 0
|
||||
__handle = __handle + 1
|
||||
return __handle - 1
|
||||
}
|
||||
}
|
||||
|
||||
var file = "fake.img"
|
||||
var imglib = DL.open("./fakeimglib.so", RTLD_LAZY)
|
||||
var imghandle = (imglib != null) ? imglib.call("openimage", file) : My.openimage(file)
|
||||
System.print("opened with handle %(imghandle)")
|
||||
if (imglib != null) imglib.close()
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
gcc -c -fpic fakeimglib.c
|
||||
gcc -shared fakeimglib.o -o fakeimglib.so
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int openimage(const char *s) {
|
||||
static int handle = 100;
|
||||
fprintf(stderr, "opening %s\n", s);
|
||||
return handle++;
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* gcc call_shared_library_function.c -o call_shared_library_function -ldl -lwren -lm */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include "wren.h"
|
||||
|
||||
/* C <=> Wren interface functions */
|
||||
|
||||
void C_dlAllocate(WrenVM* vm) {
|
||||
const char *file = wrenGetSlotString(vm, 1);
|
||||
int mode = (int)wrenGetSlotDouble(vm, 2);
|
||||
void *imglib = dlopen(file, mode);
|
||||
if (imglib == NULL) wrenSetSlotNull(vm, 0);
|
||||
void** pimglib = (void**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(void*));
|
||||
*pimglib = imglib;
|
||||
}
|
||||
|
||||
void C_call(WrenVM* vm) {
|
||||
void *imglib = *(void**)wrenGetSlotForeign(vm, 0);
|
||||
const char *symbol = wrenGetSlotString(vm, 1);
|
||||
const char *arg = wrenGetSlotString(vm, 2);
|
||||
int (*extopenimage)(const char *);
|
||||
extopenimage = dlsym(imglib, symbol);
|
||||
int imghandle = extopenimage(arg);
|
||||
wrenSetSlotDouble(vm, 0, (double)imghandle);
|
||||
}
|
||||
|
||||
void C_close(WrenVM* vm) {
|
||||
void *imglib = *(void**)wrenGetSlotForeign(vm, 0);
|
||||
dlclose(imglib);
|
||||
}
|
||||
|
||||
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
|
||||
WrenForeignClassMethods methods;
|
||||
methods.finalize = NULL;
|
||||
if (strcmp(module, "main") == 0) {
|
||||
if (strcmp(className, "DL") == 0) {
|
||||
methods.allocate = C_dlAllocate;
|
||||
}
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
|
||||
WrenForeignMethodFn bindForeignMethod(
|
||||
WrenVM* vm,
|
||||
const char* module,
|
||||
const char* className,
|
||||
bool isStatic,
|
||||
const char* signature) {
|
||||
if (strcmp(module, "main") == 0) {
|
||||
if (strcmp(className, "DL") == 0) {
|
||||
if (!isStatic && strcmp(signature, "call(_,_)") == 0) return C_call;
|
||||
if (!isStatic && strcmp(signature, "close()") == 0) return C_close;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void writeFn(WrenVM* vm, const char* text) {
|
||||
printf("%s", text);
|
||||
}
|
||||
|
||||
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
|
||||
switch (errorType) {
|
||||
case WREN_ERROR_COMPILE:
|
||||
printf("[%s line %d] [Error] %s\n", module, line, msg);
|
||||
break;
|
||||
case WREN_ERROR_STACK_TRACE:
|
||||
printf("[%s line %d] in %s\n", module, line, msg);
|
||||
break;
|
||||
case WREN_ERROR_RUNTIME:
|
||||
printf("[Runtime Error] %s\n", msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *readFile(const char *fileName) {
|
||||
FILE *f = fopen(fileName, "r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
rewind(f);
|
||||
char *script = malloc(fsize + 1);
|
||||
fread(script, 1, fsize, f);
|
||||
fclose(f);
|
||||
script[fsize] = 0;
|
||||
return script;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
WrenConfiguration config;
|
||||
wrenInitConfiguration(&config);
|
||||
config.writeFn = &writeFn;
|
||||
config.errorFn = &errorFn;
|
||||
config.bindForeignClassFn = &bindForeignClass;
|
||||
config.bindForeignMethodFn = &bindForeignMethod;
|
||||
WrenVM* vm = wrenNewVM(&config);
|
||||
const char* module = "main";
|
||||
const char* fileName = "call_shared_library_function.wren";
|
||||
char *script = readFile(fileName);
|
||||
WrenInterpretResult result = wrenInterpret(vm, module, script);
|
||||
switch (result) {
|
||||
case WREN_RESULT_COMPILE_ERROR:
|
||||
printf("Compile Error!\n");
|
||||
break;
|
||||
case WREN_RESULT_RUNTIME_ERROR:
|
||||
printf("Runtime Error!\n");
|
||||
break;
|
||||
case WREN_RESULT_SUCCESS:
|
||||
break;
|
||||
}
|
||||
wrenFreeVM(vm);
|
||||
free(script);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
option casemap:none
|
||||
|
||||
windows64 equ 1
|
||||
linux64 equ 3
|
||||
|
||||
ifndef __LIB_CLASS__
|
||||
__LIB_CLASS__ equ 1
|
||||
|
||||
if @Platform eq windows64
|
||||
option dllimport:<kernel32>
|
||||
HeapAlloc proto :qword, :dword, :qword
|
||||
HeapFree proto :qword, :dword, :qword
|
||||
ExitProcess proto :dword
|
||||
GetProcessHeap proto
|
||||
LoadLibraryA proto :qword
|
||||
FreeLibrary proto :qword
|
||||
GetProcAddress proto :qword, :qword
|
||||
option dllimport:none
|
||||
exit equ ExitProcess
|
||||
dlsym equ GetProcAddress
|
||||
dlclose equ FreeLibrary
|
||||
elseif @Platform eq linux64
|
||||
malloc proto :qword
|
||||
free proto :qword
|
||||
exit proto :dword
|
||||
dlclose proto :qword
|
||||
dlopen proto :qword, :dword
|
||||
dlsym proto :qword, :qword
|
||||
endif
|
||||
|
||||
printf proto :qword, :vararg
|
||||
|
||||
CLASS libldr
|
||||
CMETHOD getproc
|
||||
ENDMETHODS
|
||||
libname db 100 dup (0)
|
||||
plib dq ?
|
||||
ENDCLASS
|
||||
|
||||
METHOD libldr, Init, <VOIDARG>, <>, library:qword, namelen:qword
|
||||
mov rbx, thisPtr
|
||||
assume rbx:ptr libldr
|
||||
.if library != 0
|
||||
mov rcx, namelen
|
||||
mov rsi, library
|
||||
lea rdi, [rbx].libname
|
||||
rep movsb
|
||||
if @Platform eq windows64
|
||||
invoke LoadLibraryA, addr [rbx].libname
|
||||
.if rax == 0
|
||||
invoke printf, CSTR("--> Failed to load library",10)
|
||||
.else
|
||||
mov [rbx].plib, rax
|
||||
.endif
|
||||
elseif @Platform eq linux64
|
||||
invoke dlopen, addr [rbx].libname, 1
|
||||
.if rax == 0
|
||||
lea rax, [rbx].libname
|
||||
invoke printf, CSTR("--> Failed to load library %s",10), rax
|
||||
.else
|
||||
mov [rbx].plib, rax
|
||||
.endif
|
||||
endif
|
||||
.else
|
||||
invoke printf, CSTR("--> Library name to load required..",10)
|
||||
.endif
|
||||
mov rax, rbx
|
||||
assume rbx:nothing
|
||||
ret
|
||||
ENDMETHOD
|
||||
|
||||
METHOD libldr, getproc, <VOIDARG>, <>, func:qword
|
||||
local tmp:qword
|
||||
mov tmp, func
|
||||
;; Just return RAX..
|
||||
invoke dlsym, [thisPtr].libldr.plib, tmp
|
||||
ret
|
||||
ENDMETHOD
|
||||
|
||||
METHOD libldr, Destroy, <VOIDARG>, <>
|
||||
mov rbx, thisPtr
|
||||
assume rbx:ptr libldr
|
||||
.if [rbx].plib != 0
|
||||
invoke dlclose, [rbx].plib
|
||||
.endif
|
||||
assume rbx:nothing
|
||||
ret
|
||||
ENDMETHOD
|
||||
endif
|
||||
|
||||
.data
|
||||
LibName db "./somelib.l",0
|
||||
|
||||
.code
|
||||
main proc
|
||||
local ldr:ptr libldr
|
||||
|
||||
invoke printf, CSTR("--> Loading %s .. ",10), addr LibName
|
||||
mov ldr, _NEW(libldr, addr LibName, sizeof(LibName))
|
||||
ldr->getproc(CSTR("disappointment"))
|
||||
.if rax == 0
|
||||
lea rax, idisappointment
|
||||
.endif
|
||||
call rax
|
||||
_DELETE(ldr)
|
||||
invoke exit, 0
|
||||
ret
|
||||
main endp
|
||||
|
||||
idisappointment:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
invoke printf, CSTR("--> Well this is a internal disappointment..",10)
|
||||
pop rbp
|
||||
mov rax, 0
|
||||
ret
|
||||
end
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
var BN=Import("zklBigNum");
|
||||
BN(1)+2 //--> BN(3)
|
||||
Loading…
Add table
Add a link
Reference in a new issue