Call a foreign-language function: Difference between revisions

Add Standard ML version using PolyML
(Add Standard ML version using PolyML)
 
(85 intermediate revisions by 31 users not shown)
Line 17:
*   [[Use another language to call a function]]
<br><br>
=={{header|8th}}==
<syntaxhighlight lang="forth">
\ tell 8th what the function expects:
"ZZ" "strdup" func: strdup
"VZ" "free" func: free
\ call the external funcs
"abc" dup \ now we have two strings "abc" on the stack
strdup .s cr \ after strdup, you'll have the new (but duplicate) string on the stack
\ the ".s" will show both strings and you can see they are different items on the stack
free \ let the c library free the string
</syntaxhighlight>
=={{header|68000 Assembly}}==
{{works with|Sega Genesis}}
 
The Genesis uses a Z80 coprocessor to interface with its sound hardware. The Z80 executes its code from RAM, so before starting this, you have to <code>memcpy</code> the compiled program code from the Genesis cartridge ROM to the shared RAM area at $A00000. Since this task is about calling a function, we'll show the z80 code necessary to do that. Thanks to [https://www.chibiakumas.com/68000/platform2.php#LessonP20 this tutorial] for guidance on how this all works.
 
(Technically, the 68000 isn't calling the function itself, since it doesn't understand Z80 code at all; rather, it's instructing the Z80 to call and execute the function on its behalf. But this is probably as close as we'll ever get.)
 
'''Z80 Code:'''
<syntaxhighlight lang="z80">org &0000 ;execution resets here after the 68000 resets the Z80 and sends a bus request.
jr start
 
org &0038 ;in IM 1 mode, we jump here for an IRQ. But this isn't being used for this example, so we'll just silently return.
reti
 
org &0060
start:
DI
IM 1
LD SP,&2000
 
 
main: ;hardware non-maskable interrupt (NMI) jumps here (address &0066)
 
ld a,(&1F00) ;we'll only allow the 68000 to alter the contents of this memory address.
or a
jr z,main ;just keep looping until it's nonzero.
 
;by counting the bytes each instruction takes, it can be proven that this label points to &006C.
;The call opcode takes 1 byte and the operand that follows takes two bytes.
 
smc:
call &0000 ;we'll overwrite the operand at &006D-&006E with whatever function we want to call.
 
done:
jp done ;loop until next reset
 
ExampleFunction: ;ADDR: &0072($A00072)
ret ;for simplicity this does nothing but in reality you'd have it do something sound-related here.</syntaxhighlight>
 
Here's the 68000 code that will get the Z80 to call this function:
 
<syntaxhighlight lang="68000devpac">Z80_Call:
MOVE.W #$100,$A11100 ;write: z80 reset
.wait:
BTST #8,$A11100 ;read: check bit 8 to see if the z80 is busy
BNE .wait ;loop until not busy
 
 
;now we write the function address
;z80 is little-endian so we need to reverse the byte order.
;also 68000 cannot safely write words at odd addresses so we need to write as bytes.
 
MOVE.B #$72,$A0006D
MOVE.B #$00,$A0006E ;this changes the "call &0000" above to "call ExampleFunction"
 
MOVE.B #$FF,$A01F01 ;unlock the semaphore
MOVE.W #0,$A11100 ;Z80 Bus Request - after this write, the Z80 will start executing code.</syntaxhighlight>
=={{header|Ada}}==
Ada provides standard interfaces to [[C]], [[C++]], [[Fortran]] and [[Cobol]]. Other language interfaces can be provided as well, but are not mandatory. Usually it is possible to communicate to any language that supports calling conventions standard to the [[OS]] ('''cdecl''', '''stdcall''' etc).
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
 
procedure Test_C_Interface is
function strdup (s1 : Char_Array) return Chars_Ptr;
pragma Import (C, strdup, "_strdup");
 
S1 : constant String := "Hello World!";
S2 : Chars_Ptr;
begin
S2 := strdup (To_C (S1));
Put_Line (Value (S2));
Free (S2);
end Test_C_Interface;</syntaxhighlight>
=={{header|Aikido}}==
There are two ways to call a <em>native</em> function in Aikido. The first is to write a wrapper function in C++ that is invoked from the Aikido interpreter. In a C++ file:
<syntaxhighlight lang="aikido">#include <aikido.h>
extern "C" { // need C linkage
 
// define the function using a macro defined in aikido.h
AIKIDO_NATIVE(strdup) {
aikido::string *s = paras[0].str;
char *p = strdup (s->c_str());
aikido::string *result = new aikido::string(p);
free (p);
return result;
}
 
}</syntaxhighlight>
 
Then in the Aikido program:
<syntaxhighlight lang="aikido">native function strdup(s)
println (strdup ("Hello World!"))</syntaxhighlight>
 
The second way is to use a <em>raw native</em> function. These functions must adhere to a defined set of rules and can be called directly from the Aikido interpreter. In the case of <code>strdup</code> we need to play a nasty trick because it returns a pointer that we need to print as a string.
 
<syntaxhighlight lang="aikido">native function strdup (s) // declare native
native function free(p) // also need to free the result
 
var s = strdup ("hello world\n")
var p = s // this is an integer type
for (;;) {
var ch = peek (p, 1) // read a single character
if (ch == 0) {
break
}
print (cast<char>(ch)) // print as a character
p++
}
free (s) // done with the memory now</syntaxhighlight>
=={{header|ALGOL 68}}==
The designers of Algol 68 made it extremely hard to incorporate code written in other languages. To be fair, this was a long time ago when such considerations weren't thought important and one should be careful to apply Hanlon's razor.
Line 24 ⟶ 144:
 
Note that I chose a non-trivial library function because the suggested strdup() doesn't really demonstrate the technique all that well.
<langsyntaxhighlight lang="algol68">
BEGIN
MODE PASSWD = STRUCT (STRING name, passwd, INT uid, gid, STRING gecos, dir, shell);
Line 92 ⟶ 212:
FI
END
</syntaxhighlight>
</lang>
{{out}}
<pre>
root:x:0:0:root:/root:/bin/bash
</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
 
/* ARM assembly Raspberry PI */
=={{header|8th}}==
/* program forfunction.s */
<lang forth>
\ tell 8th what the function expects:
"ZZ" "strdup" func: strdup
"VZ" "free" func: free
\ call the external funcs
"abc" dup \ now we have two strings "abc" on the stack
strdup .s cr \ after strdup, you'll have the new (but duplicate) string on the stack
\ the ".s" will show both strings and you can see they are different items on the stack
free \ let the c library free the string
</lang>
=={{header|Ada}}==
Ada provides standard interfaces to [[C]], [[C++]], [[Fortran]] and [[Cobol]]. Other language interfaces can be provided as well, but are not mandatory. Usually it is possible to communicate to any language that supports calling conventions standard to the [[OS]] ('''cdecl''', '''stdcall''' etc).
<lang Ada>with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
 
/* Constantes */
procedure Test_C_Interface is
.equ STDOUT, 1 @ Linux output console
function strdup (s1 : Char_Array) return Chars_Ptr;
.equ EXIT, 1 @ Linux syscall
pragma Import (C, strdup, "_strdup");
.equ WRITE, 4 @ Linux syscall
/* Initialized data */
.data
szString: .asciz "Hello word\n"
 
/* UnInitialized data */
S1 : constant String := "Hello World!";
.bss
S2 : Chars_Ptr;
begin
S2 := strdup (To_C (S1));
Put_Line (Value (S2));
Free (S2);
end Test_C_Interface;</lang>
 
/* code section */
=={{header|Aikido}}==
.text
There are two ways to call a <em>native</em> function in Aikido. The first is to write a wrapper function in C++ that is invoked from the Aikido interpreter. In a C++ file:
.global main
<lang aikido>#include <aikido.h>
main: @ entry of program
extern "C" { // need C linkage
push {fp,lr} @ saves registers
 
ldr r0,iAdrszString @ string address
// define the function using a macro defined in aikido.h
bl strdup @ call function C
AIKIDO_NATIVE(strdup) {
@ return new pointer
aikido::string *s = paras[0].str;
bl affichageMess @ display dup string
char *p = strdup (s->c_str());
bl free @ free heap
aikido::string *result = new aikido::string(p);
free (p);
return result;
}
 
100: @ standard end of the program */
}</lang>
mov r0, #0 @ return code
pop {fp,lr} @restaur 2 registers
mov r7, #EXIT @ request to exit program
swi 0 @ perform the system call
iAdrszString: .int szString
 
/******************************************************************/
Then in the Aikido program:
/* display text with size calculation */
<lang aikido>native function strdup(s)
/******************************************************************/
println (strdup ("Hello World!"))</lang>
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registres
mov r2,#0 @ counter length
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index
cmp r1,#0 @ if 0 its over
addne r2,r2,#1 @ else add 1 in the length
bne 1b @ and loop
@ so here r2 contains the length of the message
mov r1,r0 @ address message in r1
mov r0,#STDOUT @ code to write to the standard output Linux
mov r7, #WRITE @ code call system "write"
svc #0 @ call systeme
pop {r0,r1,r2,r7,lr} @ restaur des 2 registres */
bx lr @ return
</syntaxhighlight>
=={{header|Arturo}}==
 
'''C Library'''
The second way is to use a <em>raw native</em> function. These functions must adhere to a defined set of rules and can be called directly from the Aikido interpreter. In the case of <code>strdup</code> we need to play a nasty trick because it returns a pointer that we need to print as a string.
 
<syntaxhighlight lang="c">// compile with:
<lang aikido>native function strdup (s) // declare native
// clang -c -w mylib.c
native function free(p) // also need to free the result
// clang -shared -o libmylib.dylib mylib.o
 
#include <stdio.h>
var s = strdup ("hello world\n")
 
var p = s // this is an integer type
void sayHello(char* name){
for (;;) {
printf("Hello %s!\n", name);
var ch = peek (p, 1) // read a single character
if (ch == 0) {
break
}
print (cast<char>(ch)) // print as a character
p++
}
free (s) // done with the memory now</lang>
 
int doubleNum(int num){
return num * 2;
}</syntaxhighlight>
 
'''Calling from Arturo'''
 
<syntaxhighlight lang="rebol">; call an external function directly
call.external: "mylib" 'sayHello ["John"]
 
; map an external function to a native one
doubleNum: function [num][
ensure -> integer? num
call .external: "mylib"
.expect: :integer
'doubleNum @[num]
]
 
loop 1..3 'x [
print ["The double of" x "is" doubleNum x]
]</syntaxhighlight>
 
{{out}}
 
<pre>Hello John!
The double of 1 is 2
The double of 2 is 4
The double of 3 is 6 </pre>
=={{header|AutoHotkey}}==
from the documentation for dllcall: <langsyntaxhighlight AutoHotkeylang="autohotkey">; Example: Calls the Windows API function "MessageBox" and report which button the user presses.
 
WhichButton := DllCall("MessageBox", "int", "0", "str", "Press Yes or No", "str", "Title of box", "int", 4)
MsgBox You pressed button #%WhichButton%.</langsyntaxhighlight>
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> SYS "LoadLibrary", "MSVCRT.DLL" TO msvcrt%
SYS "GetProcAddress", msvcrt%, "_strdup" TO `strdup`
SYS "GetProcAddress", msvcrt%, "free" TO `free`
Line 178 ⟶ 329:
PRINT $$address%
SYS `free`, address%
</syntaxhighlight>
</lang>
=={{header|C}}==
===Assembly via GCC===
Assembly code can be embedded and compiled via GCC.
<syntaxhighlight lang="c">
#include <stdlib.h>
#include <stdio.h>
 
int main(int argc,char** argv) {
 
int arg1 = atoi(argv[1]), arg2 = atoi(argv[2]), sum, diff, product, quotient, remainder ;
 
__asm__ ( "addl %%ebx, %%eax;" : "=a" (sum) : "a" (arg1) , "b" (arg2) );
__asm__ ( "subl %%ebx, %%eax;" : "=a" (diff) : "a" (arg1) , "b" (arg2) );
__asm__ ( "imull %%ebx, %%eax;" : "=a" (product) : "a" (arg1) , "b" (arg2) );
 
__asm__ ( "movl $0x0, %%edx;"
"movl %2, %%eax;"
"movl %3, %%ebx;"
"idivl %%ebx;" : "=a" (quotient), "=d" (remainder) : "g" (arg1), "g" (arg2) );
 
printf( "%d + %d = %d\n", arg1, arg2, sum );
printf( "%d - %d = %d\n", arg1, arg2, diff );
printf( "%d * %d = %d\n", arg1, arg2, product );
printf( "%d / %d = %d\n", arg1, arg2, quotient );
printf( "%d %% %d = %d\n", arg1, arg2, remainder );
 
return 0 ;
}
</syntaxhighlight>
Output:
<pre>
Abhishek_Ghosh@Azure:~/projects/c$ ./a.out 9 3
9 + 3 = 12
9 - 3 = 6
9 * 3 = 27
9 / 3 = 3
9 % 3 = 0
</pre>
 
===Python===
'''IMPORTANT''' : The following implementation has been tested against Python 2.7, this won't work on a system which does not have the relevant files installed. Also pay attention to the compilation flags.
<syntaxhighlight lang="c">#include <python2.7/Python.h>
 
int main()
{
Py_Initialize();
PyRun_SimpleString("a = [3*x for x in range(1,11)]");
PyRun_SimpleString("print 'First 10 multiples of 3 : ' + str(a)");
 
PyRun_SimpleString("print 'Last 5 multiples of 3 : ' + str(a[5:])");
 
PyRun_SimpleString("print 'First 10 multiples of 3 in reverse order : ' + str(a[::-1])");
Py_Finalize();
return 0;
}</syntaxhighlight>
'''Compilation''' : Change 2.7 and relevant paths for a different Python version / different install location
<pre>
$ cc callPython2.c -lpython2.7 -lm -L/usr/lib/python2.7/config
</pre>
Output :
<pre>
Abhishek_Ghosh@Azure$ ./a.out
First 10 multiples of 3 : [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
Last 5 multiples of 3 : [18, 21, 24, 27, 30]
First 10 multiples of 3 in reverse order : [30, 27, 24, 21, 18, 15, 12, 9, 6, 3]
</pre>
=={{header|C++}}==
While calling C functions from C++ is generally almost trivial, <code>strdup</code> illustrates some fine point in communicating with C libraries. However, to illustrate how to generally use C functions, a C function <code>strdup1</code> is used, which is assumed to have the same interface and behaviour as strdup, but cannot be found in a standard header.
 
In addition, this code demonstrates a call to a FORTRAN function defined as
<langsyntaxhighlight lang="cpp">FUNCTION MULTIPLY(X, Y)
DOUBLE PRECISION MULTIPLY, X, Y</langsyntaxhighlight>
Note that the calling convention of FORTRAN depends on the system and the used FORTRAN compiler, and sometimes even on the command line options used for the compiler; here, GNU Fortran with no options is assumed.
<langsyntaxhighlight lang="cpp">#include <cstdlib> // for C memory management
#include <string> // for C++ strings
#include <iostream> // for output
Line 228 ⟶ 446:
// free, not delete, nor delete[], nor operator delete
std::free(msg2);
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
{{libheader|clojure-jna}}
Since Clojure is hosted on the JVM, you can follow the same approach as the [[#Java|Java]] solution and invoke your Java class from Clojure:
<langsyntaxhighlight lang="clojure">(JNIDemo/callStrdup "Hello World!")</langsyntaxhighlight>
 
Alternatively, to avoid having to create a library in native code you could use JNA and the clojure-jna library for convenience. Here's how you can invoke ''strcmp'' from the libc shared library:
<langsyntaxhighlight lang="clojure">(require '[net.n01se.clojure-jna :as jna])
 
(jna/invoke Integer c/strcmp "apple" "banana" ) ; returns -1
Line 242 ⟶ 459:
(jna/invoke Integer c/strcmp "banana" "apple" ) ; returns 1
 
(jna/invoke Integer c/strcmp "banana" "banana" ) ; returns 0</langsyntaxhighlight>
 
=={{header|CMake}}==
''This code uses a deprecated feature of CMake.'' In 2014, CMake 3.0 deprecated load_command(). CMake 3.0 can run this code but shows a deprecation warning. When a future version of CMake removes load_command(), this code will stop working, and there will be no way to call C functions from CMake.
Line 250 ⟶ 466:
 
'''CMakeLists.txt'''
<langsyntaxhighlight lang="cmake">cmake_minimum_required(VERSION 2.6)
project("outer project" C)
 
Line 274 ⟶ 490:
2012 / 500 = ${quot}
2012 % 500 = ${rem}
")</langsyntaxhighlight>
 
'''div/CMakeLists.txt'''
<langsyntaxhighlight lang="cmake">cmake_minimum_required(VERSION 2.6)
project(div C)
 
Line 284 ⟶ 500:
 
# Compile cmDIV from div-command.c
add_library(cmDIV MODULE div-command.c)</langsyntaxhighlight>
 
'''div/div-command.c'''
<langsyntaxhighlight lang="c">#include <cmCPluginAPI.h>
#include <stdio.h>
#include <stdlib.h>
Line 341 ⟶ 557:
info->InitialPass = initial_pass;
api = info->CAPI;
}</langsyntaxhighlight>
 
=={{header|COBOL}}==
Tested with GnuCOBOL
 
<langsyntaxhighlight lang="cobol"> identification division.
program-id. foreign.
 
Line 372 ⟶ 587:
display "error calling free" upon syserr
end-if
goback.</langsyntaxhighlight>
 
{{out}}
Line 380 ⟶ 595:
Hello, world
</pre>
 
=={{header|Common Lisp}}==
 
{{libheader|CFFI}}
 
<langsyntaxhighlight lang="lisp">CL-USER> (let* ((string "Hello World!")
(c-string (cffi:foreign-funcall "strdup" :string string :pointer)))
(unwind-protect (write-line (cffi:foreign-string-to-lisp c-string))
Line 391 ⟶ 605:
(values))
Hello World!
; No value</langsyntaxhighlight>
=={{header|Crystal}}==
Crystal allows to easily interface with C functions, both from object files and shared libraries.
<syntaxhighlight lang="ruby">@[Link("c")] # name of library that is passed to linker. Not needed as libc is linked by stdlib.
lib LibC
fun free(ptr : Void*) : Void
fun strdup(ptr : Char*) : Char*
end
 
s1 = "Hello World!"
p = LibC.strdup(s1) # returns Char* allocated by LibC
s2 = String.new(p)
LibC.free p # pointer can be freed as String.new(Char*) makes a copy of data
 
puts s2</syntaxhighlight>
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio: writeln;
import std.string: toStringz;
import std.conv: to;
Line 429 ⟶ 656:
free(str1);
free(str2);
}</langsyntaxhighlight>
{{out}}
<pre>str1: Hello World!
str2: Hello World!</pre>
 
=={{header|Delphi}}==
===Importing the function from a shared library===
Line 443 ⟶ 669:
The file first has to be bound to your unit:
 
<langsyntaxhighlight lang="delphi">
{$O myhello.obj}
</syntaxhighlight>
</lang>
 
The next step is to do an external declaration for the function:
<langsyntaxhighlight lang="delphi">
procedure Hello(S: PChar); stdcall; external;
</syntaxhighlight>
</lang>
 
Afterwards usage of the function is just as with any other function.
 
=={{header|Ecstasy}}==
Ecstasy was designed around software containers and a strong security model. As such, Ecstasy does not have an FFI, and Ecstasy code cannot direcly access operating system or other foreign functions. More specifically, code running within an Ecstasy container cannot call foreign functions; any such required capabilities must be implemented outside of Ecstasy and then <i>injected</i> into an Ecstasy container.
 
=={{header|Factor}}==
Line 458 ⟶ 687:
 
libc is already loaded, it is used by Factor elsewhere.
<langsyntaxhighlight lang="factor">FUNCTION: char* strdup ( c-string s ) ;
 
: my-strdup ( str -- str' )
strdup [ utf8 alien>string ] [ (free) ] bi ;</langsyntaxhighlight>
 
( scratchpad ) "abc" my-strdup .
"abc"
 
=={{header|FBSL}}==
Alongside its interpretative BASIC-style layer, FBSL also hosts built-in Intel-style Dynamic Assembler JIT and ANSI-C Dynamic C JIT compiler layers. BASIC, DynAsm and DynC procedures can be mixed freely to best suit the host script's intended purposes. The procedures follow their own respective syntaxes but are called in the host script in exactly the same way:
Line 532 ⟶ 760:
 
FBSL features a built-in stack balancing mechanism which eliminates stack corruption regardless of whether the API calls are using STDCALL or CDECL calling conventions. Please note that FBSL's BASIC and DynAsm '''do not''' make use of forward function declarations or header files.
 
=={{header|Forth}}==
{{works with|GNU Forth|0.7.0}}
Line 538 ⟶ 765:
Every version of GNU Forth has experimented with a different means to do C foreign function calls. The current implementation resolves various incompatibilities which had plagued earlier mechanisms by parsing C header files and using the host's native toolchain (i.e. gcc and ld) to generate thunks.
 
<langsyntaxhighlight lang="forth">c-library cstrings
 
\c #include <string.h>
Line 560 ⟶ 787:
duped dup strlen type \ testing
 
duped free throw \ gforth ALLOCATE and FREE map directly to C's malloc() and free()</langsyntaxhighlight>
 
=={{header|Fortran}}==
Since Fortran 2003, the standard provides the ISO_C_BINDING module to help interface with C programs. Before this, compiler vendors often provided nonstandard extensions to do this. Even with this new facility, some features, such as calling a STDCALL function on Windows, need some nonstandard extension.
Line 571 ⟶ 797:
Here is an example using the ISO_C_BINDING standard module to link against the C API functions ''strdup'', ''free'' and ''puts''. The program will print two copies of the string ''"Hello, World!"'' using the ''puts'' function. One copy is obtained from ''strdup'', then released with ''free''. The C bindings are placed in an interface module to simplify reuse. The addresses of the two copies are also printed.
 
<langsyntaxhighlight lang="fortran">module c_api
use iso_c_binding
implicit none
Line 615 ⟶ 841:
transfer(ptr, 0_c_intptr_t)
call free(ptr)
end program</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
Normally it's an easy matter to call a function in the C Standard Library, statically, from FreeBASIC.
Line 622 ⟶ 847:
As this uses LocalAlloc in kernel32.dll internally to allocate memory for the duplicated string, we need to call
LocalFree to free this memory using the pointer returned by strdup.
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
'Using StrDup function in Shlwapi.dll
Line 641 ⟶ 866:
DyLibFree(library) '' unload first dll
DyLibFree(library2) '' unload second fll
End</langsyntaxhighlight>
 
{{out}}
<pre>
duplicate
</pre>
 
=={{header|FutureBasic}}==
The C Standary Library doesn't include the strdup() function. In the code below, strdup has been declared, written and executed in C. FB allows users to pass-through and compile C code, while it treating its execution as if it's native FB. That's what been chosen for this example.
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
BeginCDeclaration
char *strdup(const char *src);
EndC
 
BeginCFunction
char *strdup(const char *src) {
char *dst = malloc(strlen (src) + 1); // Space for length plus null
if (dst == NULL) return NULL; // No memory
strcpy(dst, src); // Copy the characters
return dst; // Return the new string
}
EndC
 
BeginCCode
NSLog( @"%s", strdup( "Hello, World!" ) );
EndC
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Hello, World!
</pre>
 
=={{header|Go}}==
Using cgo, part of the standard Go command set.
<langsyntaxhighlight lang="go">package main
 
// #include <string.h>
Line 677 ⟶ 931:
// demonstrate we have string contents intact
fmt.Println(go2)
}</langsyntaxhighlight>
Output:
<pre>
hello C
</pre>
=={{header|Hare}}==
<syntaxhighlight lang="hare">// hare run -lc ffi.ha
 
use fmt;
use strings;
 
@symbol("strdup") fn cstrdup(_: *const char) *char;
@symbol("free") fn cfree(_: nullable *void) void;
 
export fn main() void = {
let s = strings::to_c("Hello, World!");
defer free(s);
 
let dup = cstrdup(s);
fmt::printfln("{}", strings::fromc(dup))!;
cfree(dup);
};</syntaxhighlight>
=={{header|Haskell}}==
 
<langsyntaxhighlight Haskelllang="haskell">{-# LANGUAGE ForeignFunctionInterface #-}
 
import Foreign (free)
Line 699 ⟶ 969:
s2_hs <- peekCString s2 -- marshall the C string called s2 into a Haskell string named s2_hs
putStrLn s2_hs
free s2) -- s is automatically freed by withCString once done</langsyntaxhighlight>
 
==Icon and {{header|Unicon}}==
Line 707 ⟶ 977:
The first step is to create a shared library, to wrap the target C functions and do type conversions on the input and returned values. The arguments to the wrapper functions form a list, and this list must be unpacked to retrieve the arguments to send to the target function. To get at <code>strdup</code> and <code>strcat</code> we would have:
 
<syntaxhighlight lang="c">
<lang C>
#include <string.h>
#include "icall.h" // a header routine from the Unicon sources - provides helpful type-conversion macros
Line 726 ⟶ 996:
RetString (result);
}
</syntaxhighlight>
</lang>
 
Then the Unicon program must 'access' the function in the shared library: the important step is 'loadfunc' which accesses the named function in the shared library. After that, the C function can be called from within a program:
 
<syntaxhighlight lang="unicon">
<lang Unicon>
$define LIB "libstrdup-wrapper.so"
 
Line 754 ⟶ 1,024:
write (strcat ("abc", "def"))
end
</syntaxhighlight>
</lang>
 
Output:
Line 762 ⟶ 1,032:
abcdef
</pre>
 
=={{header|J}}==
 
Here is a windows specific implementation (for relatively recent versions of windows):
 
<langsyntaxhighlight Jlang="j">require 'dll'
strdup=: 'msvcrt.dll _strdup >x *' cd <
free=: 'msvcrt.dll free n x' cd <
getstr=: free ] memr@,&0 _1</langsyntaxhighlight>
 
With these definitions:
<langsyntaxhighlight Jlang="j"> getstr@strdup 'Hello World!'
Hello World!</langsyntaxhighlight>
 
Portability is possible, but often irrelevant for a task of this sort. To make this work with a different OS, you would need to use the appropriate file name for libc for the os in question. For example, on linux, replace msvcrt.dll with /lib/libc.so.6 (or whichever version of libc you are using).
 
See also: [http://www.jsoftware.com/help/user/call_procedure.htm J's documentation]
 
=={{header|Java}}==
Java uses JNI to call other languages directly. Because it is a managed language, a "shim" layer needs to be created when dealing with things outside of the managed environment.
Line 786 ⟶ 1,054:
 
'''JNIDemo.java'''
<langsyntaxhighlight lang="java">public class JNIDemo
{
static
Line 797 ⟶ 1,065:
private static native String callStrdup(String s);
}</langsyntaxhighlight>
 
Two things to note: First, the "native" stub which will be linked with a native library, and second, the call to System.loadLibrary to actually do the linking at runtime. The class must then be compiled without the native library.
Line 806 ⟶ 1,074:
 
The generated file, '''JNIDemo.h''':
<langsyntaxhighlight lang="c">/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIDemo */
Line 826 ⟶ 1,094:
}
#endif
#endif</langsyntaxhighlight>
 
Next, the C code which utilizes JNI to bridge between the managed and unmanaged environments. It should include the "h" file, and implement the exported function declared in that file. The specifics of writing JNI code are beyond the scope of this task.
 
'''JNIDemo.c'''
<langsyntaxhighlight lang="c">#include "string.h"
#include "JNIDemo.h"
 
Line 874 ⟶ 1,142:
return dupeString;
}
</syntaxhighlight>
</lang>
 
In a Windows environment, a dll by the same name should be created ("JNIDemo.dll"). In a Linux environment, a shared object marked executable and with a name preceded by "lib" should be created (in this case, "libJNIDemo.so"). Your compiler will need to know the location of "jni.h", which is in the "include" directory of the JDK. Linux may also need includes that are in the "include/linux" directory. Linux example using gcc:
Line 885 ⟶ 1,153:
Hello World!
</pre>
=={{header|JavaScript}}==
'''Node.js'''
 
Node.js provides the node-api tool to help you create native C or C++ addons.
This example will implement openssl's MD5 function in C++, and create Node.js bindings for it.
 
'''md5sum.cc'''
<syntaxhighlight lang="cpp">#include <napi.h>
#include <openssl/md5.h>
 
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
using namespace Napi;
 
Napi::Value md5sum(const Napi::CallbackInfo& info) {
std::string input = info[0].ToString();
 
unsigned char result[MD5_DIGEST_LENGTH];
MD5((unsigned char*)input.c_str(), input.size(), result);
 
std::stringstream md5string;
md5string << std::hex << std::setfill('0');
for (const auto& byte : result) md5string << std::setw(2) << (int)byte;
return String::New(info.Env(), md5string.str().c_str());
}
 
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "md5sum"),
Napi::Function::New(env, md5sum));
return exports;
}
 
NODE_API_MODULE(addon, Init)</syntaxhighlight>
Then compile the file with [https://github.com/nodejs/node-gyp node-gyp].
<syntaxhighlight lang="bash">node-gyp build</syntaxhighlight>
Once it has compiled, create the JavaScript bindings.
 
'''binding.js'''
<syntaxhighlight lang="javascript">const addon = require('../build/Release/md5sum-native');
 
module.exports = addon.md5sum;</syntaxhighlight>
Then, you're able to call the function from any Node.js JavaScript file.
 
''Using Require:''
<syntaxhighlight lang="javascript">const md5sum = require('../lib/binding.js');
console.log(md5sum('hello'));</syntaxhighlight>
{{out}}
<pre>
5d41402abc4b2a76b9719d911017c592
</pre>
''Using Import:''
 
If you wish to use the ESM import syntax, you need to modify your ''binding.js'' file.
 
'''binding.js'''
<syntaxhighlight lang="javascript">import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const addon = require('../build/Release/md5sum-native');
 
export default addon.md5sum;</syntaxhighlight>
And call the function as follows:
<syntaxhighlight lang="javascript">import md5sum from '../lib/binding.js';
 
console.log(md5sum('hello'));</syntaxhighlight>
{{out}}
<pre>
5d41402abc4b2a76b9719d911017c592
</pre>
Learn more on the Node.js [https://nodejs.org/api/addons.html docs].
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
Julia has a built-in keyword <code>ccall</code> to call external C-like functions. For example:
<langsyntaxhighlight lang="julia">p = ccall(:strdup, Ptr{Cuchar}, (Ptr{Cuchar},), "Hello world")
@show unsafe_string(p) # "Hello world"
ccall(:free, Void, (Ptr{Cuchar},), p)</syntaxhighlight>
</lang>
 
'''PyCall''', [https://github.com/JuliaPy/PyCall.jl source]:
<syntaxhighlight lang="julia">using PyCall
@pyimport math
@show math.cos(1) # 0.5403023058681398</syntaxhighlight>
=={{header|Kotlin}}==
{{Works with|Ubuntu|14.04}}
<langsyntaxhighlight lang="scala">// Kotlin Native v0.2
 
import kotlinx.cinterop.*
Line 903 ⟶ 1,246:
val hw = strdup ("Hello World!")!!.toKString()
println(hw)
}</langsyntaxhighlight>
 
{{out}}
Line 909 ⟶ 1,252:
Hello World!
</pre>
 
=={{header|LabVIEW}}==
Use Connectivity >> Libraries & Executables >> Call Library Function Node to call an external .dll file. This example uses the WinAPI's MessageBoxA function.<br/>{{VI snippet}}<br/>
[[File:LabVIEW Call a foreign-language function.png]]
 
=={{header|Lisaac}}==
Use backtick notation (`...`) for referencing foreign language (C) features.
<langsyntaxhighlight Lisaaclang="lisaac">Section Header
 
+ name := TEST_C_INTERFACE;
Line 939 ⟶ 1,280:
// this will also be inserted in-place, expression type disregarded
`free(@p)`;
);</langsyntaxhighlight>
=={{header|Locomotive Basic}}==
WinAPE has a built-in Z80 assembler that can copy the assembled program into the Amstrad CPC's memory. Whatever address your <code>org</code> directive was at can be <code>CALL</code>ed in BASIC.
 
<syntaxhighlight lang="z80">org &1000
ld a,'A'
call &bb5a
ret</syntaxhighlight>
 
{{out}}
<pre>call &1000
A
Ready</pre>
=={{header|Lua}}==
 
Using the [http://luajit.org/ext_ffi.html FFI library] available in [http://luajit.org/ LuaJIT]:
 
<langsyntaxhighlight lang="lua">local ffi = require("ffi")
ffi.cdef[[
char * strndup(const char * s, size_t n);
Line 959 ⟶ 1,311:
print("Copy: " .. s2)
print("strlen: " .. ffi.C.strlen(s2))
</syntaxhighlight>
</lang>
 
=={{header|Luck}}==
 
Luck supports interfacing with most C libraries out of the box:
 
<langsyntaxhighlight lang="luck">import "stdio.h";;
import "string.h";;
 
Line 971 ⟶ 1,322:
let s2:char* = strdup(cstring(s1));;
puts(s2);;
free(s2 as void*)</langsyntaxhighlight>
=={{header|M2000 Interpreter}}==
=== Call C Functions from Dll===
There is a difference between Windows and Wine implementation of _strdump and swprintf.
Value of '''a''' has to hold chars to read from sBuf$ as returned from msvcrt.swprintf, but this can't work in Ubuntu using Wine and in Windows as expected, so we can use '''LeftPart$(string, string as delimiter sign not included as result)'''
<syntaxhighlight lang="m2000 interpreter">
 
Module CheckCCall {
mybuf$=string$(chr$(0), 1000)
a$="Hello There 12345"+Chr$(0)
Print Len(a$)
Buffer Clear Mem as Byte*Len(a$)
\\ copy to Mem the converted a$ (from Utf-16Le to ANSI)
Return Mem, 0:=str$(a$)
Declare MyStrDup Lib C "msvcrt._strdup" { Long Ptr}
Declare MyFree Lib C "msvcrt.free" { Long Ptr}
\\ see & means by reference
\\ ... means any number of arguments
Declare MyPrintStr Lib C "msvcrt.swprintf" { &sBuf$, sFmt$, long Z }
\\ Now we use address Mem(0) as pointer (passing by value)
Long Z=MyStrDup(Mem(0))
a=MyPrintStr(&myBuf$, "%s", Z)
Print MyFree(Z), a
Print LeftPart$(chr$(mybuf$), chr$(0))
}
CheckCCall
</syntaxhighlight>
 
Output:
Hello There
 
 
===Call VbScript===
 
<syntaxhighlight lang="m2000 interpreter">
Module Checkit {
Global a()
mm=10
Module CallFromVb {
\\ Number get first parameter is numeric else error
Print Number
}
Module Global CallFromVbGlobal {
Read X()
X(0)++
a()=X()
Print "ok"
}
Declare Global vs "MSScriptControl.ScriptControl"
Declare Alfa Module
Print Type$(Alfa) \\ name is CallBack2
With vs, "Language","Vbscript", "AllowUI", true, "SitehWnd", hwnd
Method vs, "Reset"
Method vs, "AddObject", "__global__", Alfa, true
Method vs, "AddCode", {
' This is VBScript code
dim M(9), k ' 0 to 9, so 10 items
Sub main()
CallModule "CallFromVb", 1000
M(0)=1000
CallGlobal "CallFromVbGlobal", M
ExecuteStatement "Print a(0)"
k=me.Eval("a(0)")
CallModule "CallFromVb", k
' use Let to assign a number to variable
ExecuteStatement "let mm=12345"
k=me.Eval("mm")
CallModule "CallFromVb", k
CallModule "CallFromVb", M(0)
End Sub
}
Method vs, "run", "main"
Declare vs nothing
If error then print error$
Print Len(a())
Print a()
}
CheckIt
</syntaxhighlight>
 
===Call Javascript===
<syntaxhighlight lang="m2000 interpreter">
Module CheckJavaScript {
Clear
Module ok {
if match("S") then {
read m$
print "ok", m$
} else {
read m
print "ok", m
}
}
Declare vs "MSScriptControl.ScriptControl"
Declare Alfa Module
Print Type$(Alfa)
With vs, "Language","Jscript", "AllowUI", true
Method vs, "Reset"
Print Type$(Alfa)
Method vs, "AddObject", "M2000", Alfa
Inventory alfa1=1,2,3,4:="Ok"
If exist(alfa1,4) then print "Ok..."
Print type$(alfa1)
Method vs, "AddObject", "Inventory", alfa1
A=(1,2,3,4,"Hello")
Method vs, "AddObject", "Arr", A
Method vs, "ExecuteStatement", {
M2000.AddExecCode("Function BB {=1234 **number} : k=2");
M=M2000.ExecuteStatement("Print 1234, BB(k)");
// wait a key
M2000.AddExecCode("aa$=key$");
var m=[10,10+5,20];
M2000.CallModule("ok" , Inventory.count) ;
n=Inventory.Find("4");
Inventory.Value="Not Ok"
M2000.CallModule("ok" ,Inventory.Value) ;
M2000.CallModule("ok" ,Arr.Count)
Arr.item(4)="George"
Arr.item(1)++;
M2000.CallModule("ok" ,Arr.item(4))
}
Print Alfa1$(4) '' Not Ok.
Print Array$(A, 1) ' 3
Print Array$(A, 4) ' George
Modules ?
\\ BB() and K created from javascript
Print BB(k)
Method vs, "eval", {"hello there"} as X$
Print X$
Method vs, "eval", {"hello there too"} as X$
Print X$
List ' print all variables
Declare vs Nothing
}
CheckJavaScript
</syntaxhighlight>
 
 
===Call A System Function (Win32)===
<syntaxhighlight lang="m2000 interpreter">
Declare MessageBox Lib "user32.MessageBoxW" {long alfa, lptext$, lpcaption$, long type}
Print MessageBox(Hwnd, "HELLO THERE", "GEORGE", 2)
Remove "user32"
</syntaxhighlight>
 
===Make, use and remove a C Dll at runtime===
H C dll to produce an array of primes. We can
<syntaxhighlight lang="m2000 interpreter">
Module checkit {
Static DisplayOnce=0
N=100000
Read ? N
Form 60
Pen 14
Background { Cls 5}
Cls 5
\\ use f1 do unload lib - because only New statemend unload it
FKEY 1,"save ctst1:new:load ctst1"
\\ We use a function as string container, because c code can easy color decorated in M2000.
Function ccode {
long primes(long a[], long b)
{
long k=2;
long k2,d=2, l, i;
k2=k*k;
if (b>2)
{
if (k2<b)
{
do {
for (l=k2; l<=b; l+=k)
a[l]--;
k++;
while (a[k])
k++;
k2=k*k;
} while (k2<=b);
}
for (i=2;i<=b;i++)
{
if (a[i]==0)
{
a[d]=i ; d++ ;
}
}
}
else {
if (b>1)
{
if (b>2)
{
d=2; a[0]=2; a[1]=3 ;
}
else {
d=1; a[0]=2;
}
}
}
a[b+1]=d;
return 0;
}
}
\\ extract code. &functionname() is a string with the code inside "{ }"
\\ a reference to function actual is code of function in m2000
\\ using Document object we have an easy way to drop paragraphs
document code$=Mid$(&ccode(), 2, len(&ccode())-2)
\\ remove 1st line two times \\ one line for an edit information from interpreter
\\ paragraph$(code$, 1) export paragraph 1st,using third parameter -1 means delete after export.
drop$=paragraph$(code$,1,-1)+paragraph$(code$,1,-1)
If DisplayOnce Else {
Report 2, "c code for primes"
Report code$ \\ report stop after 3/4 of screen lines use. Press spacebar or mouse button to continue
DisplayOnce++
}
\\ dos "del c:\MyName.*", 200;
If not exist("c:\MyName.dll") then {
Report 2, "Now we have to make a dll"
Rem : Load Make \\ we can use a Make.gsb in current folder - this is the user folder for now
Module MAKE ( fname$, code$, timeout ) {
if timeout<1000 then timeout=1000
If left$(fname$,2)="My" Else Error "Not proper name - use 'My' as first two letters"
Print "Delete old files"
try { remove "c:\MyName" }
Dos "del c:\"+fname$+".*", timeout;
Print "Save c file"
Open "c:\"+fname$+".c" for output as F \\ use of non unicode output
Print #F, code$
Close #F
\\ use these two lines for opening dos console and return to M2000 command line
rem : Dos "cd c:\ && gcc -c -DBUILD_DLL "+fname$+".c"
rem : Error "Check for errors"
\\ by default we give a time to process dos command and then continue
Print "make object file"
dos "cd c:\ && gcc -c -DBUILD_DLL "+fname$+".c" , timeout;
if exist("c:\"+fname$+".o") then {
Print "make dll"
dos "cd c:\ && gcc -shared -o "+fname$+".dll "+fname$+".o -Wl,--out-implib,libmessage.a", timeout;
} else Error "No object file - Error"
if not exist("c:\"+fname$+".dll") then Error "No dll - Error"
}
Make "MyName", code$, 1000
}
Declare primes lib c "c:\MyName.primes" {long c, long d} \\ c after lib mean CDecl call
\\ So now we can check error
\\ make a Buffer (add two more longs for any purpose)
Buffer Clear A as Long*(N+2) \\ so A(0) is base address, of an array of 100002 long (unsign for M2000).
\\ profiler enable a timecount
profiler
Call primes(A(0), N)
m=timecount
total=Eval(A,N+1)-2
Clear Yes, No
Print "Press Y or N to display or not the primes"
Repeat {
Yes=keypress(89) : No=Keypress(78)
wait 10
} Until Yes or No
If Yes then {
Form 80,50
Refresh
For i=2 to total+1
Print Eval(A,i),
next i
Print
}
Print format$("Compute {0} primes in range 1 to {1}, in msec:{2:3}", total, N, m)
\\ unload dll, we have to use exactly the same name, as we use it in declare except for last chars ".dll"
remove "c:\MyName"
}
checkit
 
</syntaxhighlight>
=={{header|Maple}}==
We can call strdup, as requested, in the following way
<langsyntaxhighlight Maplelang="maple">> strdup := define_external( strdup, s::string, RETURN::string, LIB = "/lib/libc.so.6" ):
> strdup( "foo" );
"foo"
</syntaxhighlight>
</lang>
However, this doesn't make a lot of sense in Maple, since there can be only one copy of any Maple string in memory. Moreover, I don't see any easy way to free the memory allocated by strdup. A more sensible example for Maple follows. (It might be sensible if you wanted to compare your system library version of sin with the one built-in to Maple, for instance.)
<langsyntaxhighlight Maplelang="maple">> csin := define_external( sin, s::float[8], RETURN::float[8], LIB = "libm.so" );
csin := proc(s::numeric)
option call_external, define_external(sin, s::float[8],
Line 990 ⟶ 1,615:
 
> csin( evalf( Pi / 2 ) );
1.</langsyntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
=={{header|Mathematica}}==
This works on windows and on linux/mac (through Mono)
<langsyntaxhighlight Mathematicalang="mathematica">Needs["NETLink`"];
externalstrdup = DefineDLLFunction["_strdup", "msvcrt.dll", "string", {"string"}];
Print["Duplicate: ", externalstrdup["Hello world!"]]</langsyntaxhighlight>
output
<pre>Duplicate: Hello world!</pre>
Also there is ExternalEvaluate that can call many other languages.
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">/* Maxima is written in Lisp and can call Lisp functions.
Use load("funcs.lisp"), or inside Maxima: */
 
Line 1,009 ⟶ 1,633:
 
f(5, 6);
11</langsyntaxhighlight>
=={{header|Mercury}}==
 
Mercury is designed to interact sensibly with foreign code, even while keeping itself as pure and as safe as is possible in such circumstances. Here is an example of calling C's strdup() function from within Mercury:
 
<langsyntaxhighlight lang="mercury">:- module test_ffi.
 
:- interface.
Line 1,036 ⟶ 1,660:
io.write_string(strdup("Hello, worlds!\n"), !IO).
 
:- end_module test_ffi.</langsyntaxhighlight>
 
Only the lines wrapped in comments matter for this. The rest is an application skeleton so this can be compiled and tested.
Line 1,044 ⟶ 1,668:
After this the Mercury strdup/1 function itself is declared. For purposes of exposition it has been declared fully with types and modes. The modes, however, are redundant since by default functions in Mercury have all input parameters and an output return value. Also, the determinism is declared which is again redundant. By default Mercury functions are deterministic. That line could easily have been written thusly instead:
 
<langsyntaxhighlight lang="mercury">:- func strdup(string) = string.</langsyntaxhighlight>
 
The next block of code is the foreign_proc pragma declaration. In this declaration the language ("C") is declared, the footprint of the function is again provided, this time with variable names and modes but without the determinism, a set of properties is declared and the actual C code to be executed is provided. This last piece is trivial, but the properties themselves are worth looking more closely at.
Line 1,051 ⟶ 1,675:
 
Of note is that '''no separate C source file needs to be provided'''. The compiler takes care of putting in all the required boilerplate code necessary to conform to the specifications provided. The resulting code can be treated as much a part of the program as any native Mercury code would be: types, modes, determinism, purity, etc. all managed similarly.
 
=={{header|Modula-2}}==
The first file (Vga.c) creates the function prototypes.
<langsyntaxhighlight lang="c">#include <vga.h>
 
int Initialize (void)
Line 1,121 ⟶ 1,744:
{
*ch = vga_getkey ();
}</langsyntaxhighlight>
The next file is the definition module, but in this context it is called a '''FOREIGN MODULE'''.
<langsyntaxhighlight lang="modula2">FOREIGN MODULE Vga;
 
TYPE EGAcolour = (black, blue, green, cyan, red, pink, brown, white,
Line 1,154 ⟶ 1,777:
PROCEDURE GetKey (VAR ch : CHAR);
 
END Vga.</langsyntaxhighlight>
The third file is an example program.
<langsyntaxhighlight lang="modula2">MODULE svg01;
 
FROM InOut IMPORT Read, Write, WriteBf, WriteString;
Line 1,188 ⟶ 1,811:
Write (ch);
WriteBf;
END svg01.</langsyntaxhighlight>
 
=={{header|Modula-3}}==
Modula-3 provides many predefined interfaces to C files. Here we use <tt>Cstring</tt> which uses C string functions. Note we have to convert strings of type <tt>TEXT</tt> into C strings (NULL terminated character arrays). Also note the code requires the <tt>UNSAFE</tt> keyword because it interfaces with C (which is unsafe).
<langsyntaxhighlight lang="modula3">UNSAFE MODULE Foreign EXPORTS Main;
 
IMPORT IO, Ctypes, Cstring, M3toC;
Line 1,208 ⟶ 1,830:
M3toC.FreeCopiedS(string1);
M3toC.FreeCopiedS(string2);
END Foreign.</langsyntaxhighlight>
Output:
<pre>
string1 # string2
</pre>
=={{header|Mosaic}}==
<syntaxhighlight lang="mosaic">import clib
 
importdll msvcrt =
clang function "_strdup" (ref char)ref char
end
 
proc start=
[]char str:=z"hello strdup"
ref char str2
str2:=_strdup(&.str)
println str2
end</syntaxhighlight>
=={{header|Never}}==
Never includes libffi for access to foreign functions, but currently only supports very basic types, int, float, string. ''strdup'' will work, but the ''voidness'' of ''free'' is not yet supported. This solution uses some of the Math functions in libm instead.
 
<syntaxhighlight lang="fsharp">extern "libm.so.6" func sinhf(x : float) -> float
extern "libm.so.6" func coshf(x : float) -> float
extern "libm.so.6" func powf(base : float, exp : float) -> float
extern "libm.so.6" func atanf(x : float) -> float
 
func main() -> int
{
var v1 = sinhf(1.0);
var v2 = coshf(1.0);
var v3 = powf(10.0, 2.0);
var pi = 4.0 * atanf(1.0);
 
printf(v1);
printf(v2);
printf(v3);
printf(pi);
printf(sinhf(1.0));
 
0
}</syntaxhighlight>
 
 
{{out}}
<pre>prompt$ never -f callffi.nev
1.18
1.54
100.00
3.14
1.18
</pre>
=={{header|NewLISP}}==
newLISP has two FFI APIs. The simple API needs no type specifiers but is limited to integers and pointers.
The extended API can specify types for return values and parameters and can also be used for floats and structs.
<langsyntaxhighlight NewLISPlang="newlisp">; simple FFI interface on Mac OSX
(import "libc.dylib" "strdup")
(println (get-string (strdup "hello world")))
Line 1,224 ⟶ 1,891:
(import "libc.dylib" "strdup" "char*" "char*")
(println (strdup "hello world"))
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
Since Nim compiles to C by default, this task is easily done:
 
<langsyntaxhighlight lang="nim">proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.}
echo strcmp("abc", "def")
echo strcmp("hello", "hello")
Line 1,236 ⟶ 1,902:
 
var x = "foo"
printf("Hello %d %s!\n", 12, x)</langsyntaxhighlight>
 
=={{header|OCaml}}==
 
===Outline of what is linked against===
For the hypothetical [[C]] library that contains functions described by a header file with this in:
<langsyntaxhighlight lang="ocaml">void myfunc_a();
float myfunc_b(int, float);
char *myfunc_c(int *, int);</langsyntaxhighlight>
 
The header file is named "<tt>mylib.h</tt>", and linked against the library with <tt>-lmylib</tt> and compiled with <tt>-I/usr/include/mylib</tt>.
Line 1,251 ⟶ 1,916:
 
====file "mylib.ml":====
<langsyntaxhighlight lang="ocaml">external myfunc_a: unit -> unit = "caml_myfunc_a"
external myfunc_b: int -> float -> float = "caml_myfunc_b"
external myfunc_c: int array -> string = "caml_myfunc_c"</langsyntaxhighlight>
 
====file "wrap_mylib.c":====
<langsyntaxhighlight lang="c">#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <mylib.h>
Line 1,267 ⟶ 1,932:
 
CAMLprim value
caml_myfunc_b(value a;, value b) {
float c = myfunc_b(Int_val(a), Double_val(b));
return caml_copy_double(c);
Line 1,282 ⟶ 1,947:
arr[i] = Int_val(Field(ml_array, i));
}
s = myfunc_c(arr, len);
free(arr);
return caml_copy_string(s);
}</langsyntaxhighlight>
 
====the Makefile:====
(replace spaces by tabs)
<lang makefile>wrap_mylib.o: wrap_mylib.c
<syntaxhighlight lang="makefile">wrap_mylib.o: wrap_mylib.c
ocamlc -c -ccopt -I/usr/include/mylib $<
 
Line 1,313 ⟶ 1,979:
 
clean:
rm -f *.[oa] *.so *.cm[ixoa] *.cmxa</langsyntaxhighlight>
 
the file <tt>mylib.cma</tt> is used for the interpreted and bytecode modes, and <tt>mylib.cmxa</tt> is for the native mode.
 
 
===Using ocaml-ctypes===
 
There is another solution for calling C functions from a C library which is to use '''ocaml-ctypes'''. We can then define bindings by writing only OCaml code without any C stubs. The equivalent for wrapping the previous hypothetical [[C]] library will be:
 
<syntaxhighlight lang="ocaml">open Ctypes
open Foreign
 
let myfunc_a = foreign "myfunc_a" (void @-> returning void)
let myfunc_b = foreign "myfunc_b" (int @-> float @-> returning float)
let myfunc_c = foreign "myfunc_c" (ptr void @-> int @-> returning string)
 
let myfunc_c lst =
let arr = CArray.of_list int lst in
myfunc_c (to_voidp (CArray.start arr)) (CArray.length arr)
;;</syntaxhighlight>
=={{header|Ol}}==
<syntaxhighlight lang="scheme">
(import (otus ffi))
 
(define self (load-dynamic-library #f))
(define strdup (self type-string "strdup" type-string))
 
(print (strdup "Hello World!"))
</syntaxhighlight>
 
Windows has no a "strdup" function, so windows version should look like this.
<syntaxhighlight lang="scheme">
(import (otus ffi))
 
(if (not (has? *features* 'Windows))
(print "The host platform is not a Windows!"))
 
(define self (load-dynamic-library "shlwapi.dll"))
(define strdup (self type-string "StrDupA" type-string))
 
(print (strdup "Hello World!"))
</syntaxhighlight>
 
Note: this simplest way is not freeing allocated by "strdup" function string.
 
Ol provides a way to call ol functions directly from native code (means callbacks).
<syntaxhighlight lang="scheme">
; The sample usage of GTK3+ library
(import (otus ffi)
(lib glib-2)
(lib gtk-3))
 
(define print_hello (vm:pin (cons
(list GtkWidget* gpointer)
(lambda (widget userdata)
(print "hello")
TRUE
))))
 
(define activate (vm:pin (cons
(list GtkApplication* gpointer)
(lambda (app userdata)
(define window (gtk_application_window_new app))
(print "window: " window)
(gtk_window_set_title window "Window")
(gtk_window_set_default_size window 200 200)
 
(define button_box (gtk_button_box_new GTK_ORIENTATION_HORIZONTAL))
(gtk_container_add window button_box)
 
(define button (gtk_button_new_with_label "Hello World"))
(g_signal_connect button "clicked" (G_CALLBACK print_hello) NULL)
(gtk_container_add button_box button)
 
(gtk_widget_show_all window)
))))
 
(define app (gtk_application_new (c-string "org.gtk.example") G_APPLICATION_FLAGS_NONE))
(g_signal_connect app (c-string "activate") (G_CALLBACK activate) NULL)
 
(g_application_run app 0 #false)
</syntaxhighlight>
 
=={{header|Odin}}==
 
<syntaxhighlight lang="odin">package main
 
import "core:fmt"
 
foreign import libc "system:c"
 
@(default_calling_convention="c")
foreign libc {
@(link_name="strdup") cstrdup :: proc(_: cstring) -> cstring ---
@(link_name="free") cfree :: proc(_: rawptr) ---
}
 
main :: proc() {
s1 : cstring = "hello"
s2 := cstrdup(s1)
fmt.printf("{}\n", s2)
cfree(rawptr(s2))</syntaxhighlight>
 
=={{header|Oz}}==
First we need to create a so-called "native functor" that converts the arguments and describes the C functions:
<langsyntaxhighlight lang="cpp">#include "mozart.h"
#include <string.h>
 
Line 1,339 ⟶ 2,104:
};
return table;
}</langsyntaxhighlight>
 
Save this file as "strdup.cc". To automate compiling and linking, we need a makefile for <code>ozmake</code>, the Oz build tool. Save this file as "makefile.oz":
<langsyntaxhighlight lang="oz">makefile(
lib : [
'strdup.o' 'strdup.so'
]
rules:o('strdup.so':ld('strdup.o'))
)</langsyntaxhighlight>
Call <code>ozmake</code> in the same directory.
 
Now we can write some code that uses the wrapped C function (make sure Emacs' working directory is set to the same directory):
 
<langsyntaxhighlight lang="oz">declare
[Strdup] = {Module.link ['strdup.so{native}']}
in
{System.showInfo {Strdup.strdup "hello"}}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
Of course it is trivial to include C functions in PARI, and not uncommon. C++ functions are similar, as PARI is written in a C++-friendly style. The <code>system</code> and <code>install</code> commands allow foreign-language functions to be called from within gp.
 
=={{header|Pascal}}==
See [[Call_a_foreign-language_function#Delphi | Delphi]]
 
=={{header|Perl}}==
Perl code calls a C function <code>c_dup()</code> passing a string <code>'Hello'</code> as an argument, which gets transparently converted to a C string, the <code>c_dup()</code> function makes a copy of that string using <code>strdup()</code> function, stores pointer to the copy in the <code>copy</code> variable and returns it. The returned <code>char</code> pointer gets converted transparently to a Perl string value and gets returned to the calling Perl code which prints it. Then the Perl code calls a C function <code>c_free()</code> to free the allocated memory. Both of the C functions are defined inline in the Perl program and are automatically compiled (only once, unless they change) and linked at runtime. Here is the entire program:
<langsyntaxhighlight lang="perl">use Inline C => q{
char *copy;
char * c_dup(char *orig) {
Line 1,375 ⟶ 2,137:
};
print c_dup('Hello'), "\n";
c_free();</langsyntaxhighlight>
 
Another example, instead of returning the copy to Perl code it prints it using C printf:
<langsyntaxhighlight lang="perl">use Inline C => q{
void c_hello (char *text) {
char *copy = strdup(text);
Line 1,385 ⟶ 2,147:
}
};
c_hello 'world';</langsyntaxhighlight>
=={{header|Perl 6}}==
{{Works with|rakudo|2016.07}}
<lang perl6>use NativeCall;
 
sub strdup(Str $s --> OpaquePointer) is native {*}
sub puts(OpaquePointer $p --> int32) is native {*}
sub free(OpaquePointer $p --> int32) is native {*}
 
my $p = strdup("Success!");
say 'puts returns ', puts($p);
say 'free returns ', free($p);</lang>
{{out}}
<pre>Success!
puts returns 9
free returns 0</pre>
 
=={{header|Phix}}==
The foreign language functions must be compiled to .dll (or .so) form.<br>
Line 1,407 ⟶ 2,153:
a library component which can be re-used in different applications.<br>
See also builtins/cffi.e, a text-based C interface that handles C-style structs, unions, and function declarations directly.
<!--<syntaxhighlight lang="phix">(notonline)-->
<lang Phix>constant shlwapi = open_dll("shlwapi.dll")
<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>
constant xStrDup = define_c_func(shlwapi,"StrDupA",{C_PTR},C_PTR)
<span style="color: #008080;">constant</span> <span style="color: #000000;">shlwapi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">open_dll</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"shlwapi.dll"</span><span style="color: #0000FF;">),</span>
constant kernel32 = open_dll("kernel32.dll")
<span style="color: #000000;">kernel32</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">open_dll</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"kernel32.dll"</span><span style="color: #0000FF;">)</span>
constant xLocalFree = define_c_func(kernel32,"LocalFree",{C_PTR},C_PTR)
<span style="color: #008080;">constant</span> <span style="color: #000000;">xStrDup</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shlwapi</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"StrDupA"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">C_PTR</span><span style="color: #0000FF;">},</span><span style="color: #000000;">C_PTR</span><span style="color: #0000FF;">),</span>
constant HelloWorld = "Hello World!"
<span style="color: #000000;">xLocalFree</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">kernel32</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"LocalFree"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">C_PTR</span><span style="color: #0000FF;">},</span><span style="color: #000000;">C_PTR</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">HelloWorld</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Hello World!"</span>
atom pMem = c_func(xStrDup,{HelloWorld})
?peek_string(pMem)
<span style="color: #004080;">atom</span> <span style="color: #000000;">pMem</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xStrDup</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">HelloWorld</span><span style="color: #0000FF;">})</span>
if c_func(xLocalFree,{pMem})!=NULL then ?9/0 end if</lang>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">peek_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pMem</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xLocalFree</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">pMem</span><span style="color: #0000FF;">})==</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
"Hello World!"
</pre>
=={{header|PHP}}==
{{works with|PHP|7.4}}
 
PHP 7.4+ has as support to call external C-like functions using extension . See this Windows example:
<syntaxhighlight lang="php">$ffi = FFI::cdef("char *_strdup(const char *strSource);", "msvcrt.dll");
 
$cstr = $ffi->_strdup("success");
$str = FFI::string($cstr);
echo $str;
FFI::free($cstr);
</syntaxhighlight>
=={{header|PicoLisp}}==
The easiest is to inline the C code. Another possibility would be to write it
Line 1,430 ⟶ 2,189:
 
===32-bit version===
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/gcc.l")
 
(gcc "str" NIL # The 'gcc' function passes all text
Line 1,448 ⟶ 2,207:
/**/
 
(println 'Duplicate (duptest "Hello world!"))</langsyntaxhighlight>
===64-bit version===
<syntaxhighlight lang="c">
<lang PicoLisp>(load "@lib/native.l")
/*
 
How to create the shared lib/so file:
(gcc "str" NIL
gcc -c -Wall (duptest-Werror (Str)-fPIC duptest 'S Str) ).c
gcc -shared -o duptest.so duptest.o -Wno-undef
*/
 
#include <stdlib.h>
#include <string.h>
 
extern char * duptest(char * str) {;
static char *s;
 
char * duptest(char * str) {
static char * s;
free(s); // We simply dispose the result of the last call
return s = strdup(str);
}
/**/
 
int main() {
(println 'Duplicate (duptest "Hello world!"))</lang>
}
</syntaxhighlight>
 
<syntaxhighlight lang="picolisp">
Output in both cases:
(prinl "Calling custom so/dll library...")
<pre>Duplicate "Hello world!"</pre>
(set 'A NIL)
(set 'A (native "./duptest.so" "duptest" 'S "abc"))
(prinl "A=" A)
(when (not (= A NIL)) (prinl "Success!"))
</syntaxhighlight>
 
<out>
<pre>
Calling custom so/dll library...
A=abc
Success!
</pre>
</out>
=={{header|PL/I}}==
<syntaxhighlight lang="text">declare strdup entry (character (30) varyingz) options (fastcall16);
 
put (strdup('hello world') );</lang>
 
put (strdup('hello world') );</syntaxhighlight>
=={{header|Prolog}}==
In SWI-Prolog we need to do two things. First we need to declare a mapping from a Prolog file to a C implementation:
 
<langsyntaxhighlight lang="prolog">:- module(plffi, [strdup/2]).
:- use_foreign_library(plffi).</langsyntaxhighlight>
 
This declares a module "plffi" that exports the '''predicate''' (''not'' function!) "strdup/2". This predicate has two arguments: the first being the atom being strduped, the second being the duped atom. (You can think of these as an in parameter and an out parameter and be about 2/3 right.)
Line 1,486 ⟶ 2,261:
Then we need to write a C file that gives us the interface to the underlying C function (strdup in this case), mapping the ''predicate''' call to a C '''function''' call:
 
<langsyntaxhighlight lang="c">#include <string.h>
#include <stdio.h>
#include <SWI-Prolog.h>
Line 1,505 ⟶ 2,280:
{
PL_register_foreign("strdup", 2, pl_strdup, 0);
}</langsyntaxhighlight>
 
This C code provides us with two things. The function install_plffi() is provided to register the name "strdup" and to map it to its C implementation pl_strdup(). Here we're saying that "strdup" has an arity of 2, is implemented by pl_strdup and has no special flags.
Line 1,513 ⟶ 2,288:
We compile this very easily:
 
<langsyntaxhighlight lang="sh">$ swipl-ld -o plffi -shared plffi.c</langsyntaxhighlight>
 
Then, from within the SWI-Prolog interactor:
 
<langsyntaxhighlight Prologlang="prolog">?- [plffi].
% plffi compiled into plffi 0.04 sec, 1,477 clauses
true.
Line 1,531 ⟶ 2,306:
 
?- X = booger, strdup(booger, X).
X = booger.</langsyntaxhighlight>
 
=={{header|PureBasic}}==
Here we will use [http://flatassembler.net/ Fasm (flat assembler)] to create an object file and then import the function
Line 1,538 ⟶ 2,312:
the resulting executable. [http://www.purebasic.com/ PureBasic] supports {Windows, Linux, MacOS}.
 
<syntaxhighlight lang="purebasic">
<lang PureBasic>
; Call_a_foreign_language_function.fasm -> Call_a_foreign_language_function.obj
; the assembler code...
Line 1,578 ⟶ 2,352:
 
public strucase as "_strucase@4"
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="purebasic">
<lang PureBasic>
; the PureBasic code...
 
Line 1,591 ⟶ 2,365:
; cw(peeks(*r))
Debug peeks(*r)
</syntaxhighlight>
</lang>
 
 
Line 1,598 ⟶ 2,372:
HELLO WORLD!!
</pre>
 
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">import ctypes
libc = ctypes.CDLL("/lib/libc.so.6")
libc.strcmp("abc", "def") # -1
libc.strcmp("hello", "hello") # 0</langsyntaxhighlight>
 
 
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket/base
(require ffi/unsafe)
Line 1,651 ⟶ 2,421:
;; Let's try it:
(strdup "Hello World!")
</syntaxhighlight>
</lang>
=={{header|Raku}}==
 
(formerly Perl 6)
{{Works with|rakudo|2016.07}}
<syntaxhighlight lang="raku" line>use NativeCall;
 
sub strdup(Str $s --> Pointer) is native {*}
sub puts(Pointer $p --> int32) is native {*}
sub free(Pointer $p --> int32) is native {*}
 
my $p = strdup("Success!");
say 'puts returns ', puts($p);
say 'free returns ', free($p);</syntaxhighlight>
{{out}}
<pre>Success!
puts returns 9
free returns 0</pre>
=={{header|REALbasic}}==
<syntaxhighlight lang="vb">
<lang vb>
Declare Function CreateFileW Lib "Kernel32" (FileName As WString, DesiredAccess As Integer, ShareMode As Integer, SecurityAttributes As Integer, _
CreateDisposition As Integer, Flags As Integer, Template As Integer) As Integer
Line 1,679 ⟶ 2,462:
MsgBox("Error Number: " + Str(GetLastError))
End If
</syntaxhighlight>
</lang>
 
=={{header|REXX}}==
The use of the &nbsp; '''address''' &nbsp; statement isn't normally required, but it's shown here as an illustrative example.
<langsyntaxhighlight lang="rexx">/*REXX program calls (invoke) a "foreign" (non-REXX) language routine/program. */
 
cmd = "MODE" /*define the command that is to be used*/
opts= 'CON: CP /status' /*define the options to be used for cmd*/
 
address 'SYSTEM' cmd opts /*invoke a cmd via the SYSTEM interface*/
 
/*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when executing under a Microsoft Windows system in the USA, &nbsp; code pages vary upon the country:}}
<pre>
Status for device CON:
Line 1,697 ⟶ 2,479:
Code page: 437
</pre>
 
 
 
=={{header|Ruby}}==
 
Line 1,711 ⟶ 2,490:
 
{{works with|MRI}}
<langsyntaxhighlight lang="c">/* rc_strdup.c */
#include <stdlib.h> /* free() */
#include <string.h> /* strdup() */
Line 1,744 ⟶ 2,523:
VALUE mRosettaCode = rb_define_module("RosettaCode");
rb_define_module_function(mRosettaCode, "strdup", rc_strdup, 1);
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ruby"># extconf.rb
require 'mkmf'
create_makefile('rc_strdup')</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ruby"># demo.rb
require 'rc_strdup'
puts RosettaCode.strdup('This string gets duplicated.')</langsyntaxhighlight>
 
=== FFI ===
Line 1,758 ⟶ 2,537:
A recent effort to make it easier to write libraries, portable across platforms and interpreters, led to the creation of a [http://sourceware.org/libffi/ libffi] binding simply called [http://wiki.github.com/ffi/ffi/ ffi] for completely dynamic calls.
 
<langsyntaxhighlight lang="ruby">
require 'ffi'
 
Line 1,773 ⟶ 2,552:
puts duplicate.get_string(0)
LibC.free(duplicate)
</syntaxhighlight>
</lang>
 
 
Line 1,781 ⟶ 2,560:
 
{{works with|Ruby|2.0+}}
<langsyntaxhighlight lang="ruby">require 'fiddle'
 
# Find strdup(). It takes a pointer and returns a pointer.
Line 1,793 ⟶ 2,572:
duplicate = strdup.call("This is a string!")
puts duplicate.to_s # Convert the C string to a Ruby string.
Fiddle.free duplicate # free() the memory that strdup() allocated.</langsyntaxhighlight>
 
Fiddle::Importer is also part of Ruby's standard library.
 
{{works with|Ruby|2.0+}}
<langsyntaxhighlight lang="ruby">require 'fiddle'
require 'fiddle/import'
 
Line 1,809 ⟶ 2,588:
duplicate = C.strdup("This is a string!")
puts duplicate.to_s
Fiddle.free duplicate</langsyntaxhighlight>
 
=== RubyInline ===
Line 1,815 ⟶ 2,594:
Using {{libheader|RubyGems}} package [http://www.zenspider.com/ZSS/Products/RubyInline/ RubyInline], which compiles the inlined code on demand during runtime.
 
<langsyntaxhighlight lang="ruby">require 'rubygems'
require 'inline'
 
Line 1,847 ⟶ 2,626:
t = InlineTester.new
11.upto(14) {|n| p [n, t.factorial_ruby(n), t.factorial_c(n)]}
p t.my_ilogb(1000)</langsyntaxhighlight>
 
outputs (note Ruby's implicit use of Bignum past 12!, while C is stuck with a long int):
Line 1,855 ⟶ 2,634:
[14, 87178291200, 1278945280]
9</pre>
 
=={{header|Rust}}==
 
<langsyntaxhighlight lang="rust">extern crate libc;
 
//c function that returns the sum of two integers
Line 1,870 ⟶ 2,648:
add_input(in1, in2) };
assert!( (output == (in1 + in2) ),"Error in sum calculation") ;
}</langsyntaxhighlight>
=={{header|Scala}}==
<syntaxhighlight lang="scala">object JNIDemo {
try System.loadLibrary("JNIDemo")
 
private def callStrdup(s: String)
 
println(callStrdup("Hello World!"))
}</syntaxhighlight>
=={{header|Smalltalk}}==
The way external functions are declared is different among Smalltalk dialects. However, there are not many situations where you'd need them (and especially not for simple things like strdup).
 
{{works with | Smalltalk/X}}
<syntaxhighlight lang="smalltalk">Object subclass:'CallDemo'!
!CallDemo class methods!
strdup:arg
<cdecl: mustFree char* 'strdup' (char*) module:'libc'>
! !
 
Transcript showCR:( CallDemo strdup:'Hello' )</syntaxhighlight>
 
=={{header|Standard ML}}==
{{works with|Poly/ML}}
<syntaxhighlight lang="sml">local
val libc = Foreign.loadLibrary "libc.so.6"
val sym = Foreign.getSymbol libc "strdup"
in
val strdup = Foreign.buildCall1(sym, (Foreign.cString), Foreign.cString)
end</syntaxhighlight>
{{out}}
<pre>
> strdup "test string";
val it = "test string": string
>
</pre>
 
=={{header|Stata}}==
Here are examples showing how to build and call from Stata a plugin written in C or Java. See also the entries 29 to 32 in the ''[https://blog.stata.com/2016/01/15/programming-an-estimation-command-in-stata-a-map-to-posted-entries/ Programming an estimation command in Stata]'' series by David M. Drukker, on [https://blog.stata.com/ Stata Blog].
 
=== Calling C ===
It's possible to call a C program from Stata using a '''[https://www.stata.com/plugins/ plugin]'''. A plugin is a C program that is compiled to a DLL, then used as any other command in Stata after being loaded.
Line 1,878 ⟶ 2,692:
As an example let's build a '''[https://en.wikipedia.org/wiki/Hilbert_matrix Hilbert matrix]''' in C.
 
<langsyntaxhighlight lang="c">#include <stdlib.h>
#include "stplugin.h"
 
Line 1,891 ⟶ 2,705:
}
return 0;
}</langsyntaxhighlight>
 
The DLL can be built from '''Visual Studio''', or in the console with '''<code>cl /LD hilbertmat.c stplugin.c</code>. With '''MinGW''', compile with <code>gcc -shared stplugin.c hilbertmatrix.c -o hilbertmat.plugin</code>. With '''Pelles C''', compile with <code>cc /Tx64-coff /Ze stplugin.c hilbertmat.c /DLL /OUT:hilbertmat.plugin</code>. The DLL must be renamed with the '''.plugin''' extension, and put in a directory visible in [https://www.stata.com/help.cgi?adopath adopath].
 
Declare also an ADO file to call the plugin:
 
<langsyntaxhighlight lang="stata">program hilbert
matrix define `1'=J(`2',`2',0)
plugin call hilbertmat, `1' `2'
end
 
program hilbertmat, plugin</langsyntaxhighlight>
 
Then, you may call
 
<langsyntaxhighlight lang="stata">. hilbert mymat 4
 
. matrix list mymat
Line 1,915 ⟶ 2,729:
r2 .5 .33333333
r3 .33333333 .25 .2
r4 .25 .2 .16666667 .14285714</langsyntaxhighlight>
 
Notice the program as is has minimal protection against invalid arguments. Production code should be more careful.
Line 1,924 ⟶ 2,738:
As an example let's build a '''[https://en.wikipedia.org/wiki/Hilbert_matrix Hilbert matrix]''' in Java.
 
<langsyntaxhighlight lang="java">import com.stata.sfi.*;
 
public class HilbertMatrix {
Line 1,939 ⟶ 2,753:
return 0;
}
}</langsyntaxhighlight>
 
Compile with <code>javac -cp %STATA%\utilities\jar\sfi-api.jar HilbertMatrix.java</code>, assuming %STATA% is the path to the Stata install directory.
 
In Stata, assuming HilbertMatrix.class resides in K:\java:
 
<langsyntaxhighlight lang="stata">. javacall HilbertMatrix run, classpath(K:\java) args(mymat 4)
 
. matrix list mymat
Line 1,952 ⟶ 2,768:
r2 .5 .33333333
r3 .33333333 .25 .2
r4 .25 .2 .16666667 .14285714</langsyntaxhighlight>
 
Notice that Mata has the builtin function '''[https://www.stata.com/help.cgi?mf_Hilbert Hilbert]''' to do the same:
 
<langsyntaxhighlight lang="stata">. mata: Hilbert(4)
[symmetric]
1 2 3 4
Line 1,964 ⟶ 2,780:
3 | .3333333333 .25 .2 |
4 | .25 .2 .1666666667 .1428571429 |
+---------------------------------------------------------+</langsyntaxhighlight>
 
=={{header|Swift}}==
Because Swift uses the Objective-C runtime it is trivial to call C/Objective-C functions directly in Swift.
<langsyntaxhighlight Swiftlang="swift">import Foundation
 
let hello = "Hello, World!"
let fromC = strdup(hello)
let backToSwiftString = String.fromCString(fromC)</langsyntaxhighlight>
 
=={{header|Tcl}}==
{{libheader|critcl}}
In this solution, we wrap up the <code>ilogb</code> function from C's math library with critcl so that it becomes one of Tcl's normal functions (assuming Tcl 8.5):
<langsyntaxhighlight lang="tcl">package require critcl
critcl::code {
#include <math.h>
Line 1,984 ⟶ 2,798:
return ilogb(value);
}
package provide ilogb 1.0</langsyntaxhighlight>
Note that we do not show <code>strdup</code> here because Tcl manages the memory for strings in complex ways and does not guarantee to preserve string pointers from one call into the C API to the next (e.g., if it has to apply an encoding transformation behind the scenes).
<!-- TODO: a basic thunk, and show off using SWIG -->
 
=={{header|TXR}}==
 
Line 2,004 ⟶ 2,817:
There is no way to use the <code>str</code> family of types, yet do manual memory management; FFI manages automatically. Code that wants to manually manage a foreign resource referenced by pointer should use <code>cptr</code> or <code>carray</code>, depending on required semantics.
 
=={{header|V (Vlang)}}==
Note: Vlang also has a C2V transpiler.
<syntaxhighlight lang="vlang">
#include "stdlib.h"
#include "string.h"
 
// Declare C functions that will be used.
fn C.strdup(txt &char) &char
fn C.strcat(dest &char, src &char) &char
 
fn main() {
txt_1 := "Hello World!"
txt_2 := " Let's Wish for Peace!"
// Memory-unsafe operations must be marked as such (unsafe {...}), or won't compile.
unsafe {
dup := C.strdup(txt_1.str)
println('${cstring_to_vstring(dup)}')
addto := C.strcat(dup, txt_2.str)
println('${cstring_to_vstring(addto)}')
 
// Must manually free memory or program can hang because unsafe.
free(dup)
free(addto)
}
exit(0)
}
</syntaxhighlight>
 
{{out}}
<pre>
Hello World!
Hello World! Let's Wish for Peace!
</pre>
 
=={{header|Wren}}==
Although RC task solutions are usually written for execution by Wren CLI, the language's main purpose is for embedding and the embedding API is written in C. It is therefore a relative easy matter to call a C function from Wren after first embedding the latter in a suitable C program.
 
<syntaxhighlight lang="wren">/* Call_a_foreign-language_function.wren */
 
class C {
foreign static strdup(s)
}
 
var s = "Hello World!"
System.print(C.strdup(s))</syntaxhighlight>
 
which we embed in the following C program and run it.
 
Note that it's safe to free the pointer returned by strdup after passing it to Wren because wrenSetSlotString copies the C string to a new String object managed by Wren’s garbage collector.
<syntaxhighlight lang="c">#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "wren.h"
 
void C_strdup(WrenVM* vm) {
const char *s = wrenGetSlotString(vm, 1);
char *t = strdup(s);
wrenSetSlotString(vm, 0, t);
free(t);
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "strdup(_)") == 0) {
return C_strdup;
}
}
}
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() {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "Call_a_foreign-language_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;
}</syntaxhighlight>
 
{{out}}
<pre>
Hello World!
</pre>
 
=={{header|X86-64 Assembly}}==
===UASM 2.52===
Calling C functions in Assembly is trivial at best. It's not anymore complicated than using them in C itself. Strdup for example..
<syntaxhighlight lang="asm">
option casemap:none
 
strdup proto :qword
printf proto :qword, :vararg
exit proto :dword
 
.data
bstr db "String 1",0
 
.data?
buff dq ?
 
.code
main proc
invoke printf, CSTR("Copying %s to buff with strdup using invoke....",10), addr bstr
invoke strdup, addr bstr
mov buff, rax
invoke printf, CSTR("buff now = %s",10), buff
invoke exit, 0
ret
main endp
end
;Now, we could target a specific ABI by assigning the call values to the registers like
;.code
;main proc
; lea rdi, bstr
; call strdup
; mov buff, rax
;main endp
;end
</syntaxhighlight>
====Lua====
Using the liblua that comes with Lua 5.2(?). Assembling is the same as always, Link with a -llua using clang or gcc.
<syntaxhighlight lang="asm">
option casemap:none
 
windows64 equ 1
linux64 equ 3
 
ifndef __LUA_CLASS__
__LUA_CLASS__ equ 1
 
 
LUA_OK equ 0
LUA_YEILD equ 1
LUA_ERRRUN equ 2
LUA_ERRSYNTAX equ 3
LUA_ERRMEM equ 4
;; Lua variable types - defined in lua.h
LUA_TNONE equ -1
LUA_TNIL equ 0
LUA_TBOOL equ 1
LUA_TNUMB equ 3
LUA_TSTRING equ 4
LUA_TFUNC equ 6
LUA_MULTRET equ -1
 
;; to pop or not to pop, that is the question..
DO_POP equ 1
NO_POP equ 0
 
if @Platform eq windows64
option dllimport:<kernel32>
GetProcessHeap proto
ExitProcess proto :dword
HeapAlloc proto :qword, :dword, :qword
HeapFree proto :qword, :dword, :qword
option dllimport:none
exit equ ExitProcess
elseif @Platform eq linux64
malloc proto SYSTEMV :qword
free proto SYSTEMV :qword
endif
 
printf proto :qword, :vararg
exit proto :dword
;; Lua.h funcs
luaL_newstate proto ;; lua_State *luaL_newstate();
lua_gettop proto :qword ;; int lua_getopt(lua_State *L);
lua_close proto :qword ;; void lua_close(lua_State *L);
luaL_openlibs proto :qword ;; int luaL_openlibs(lua_State *L);
lua_pushnil proto :qword ;; void lua_pushnil(lua_State *L);
lua_pushinteger proto :qword, :qword ;; void lua_pushinteger(lua_State *L, lua_Integer arg);
lua_settop proto :qword, :dword ;; int lua_setopt(lua_State *L, int idx);
lua_setglobal proto :qword, :qword ;; void lua_setglobal(lua_State *L, const char *var);
lua_getglobal proto :qword, :qword ;; int lua_getglobal(lua_State *L, const char *gn);
luaL_loadstring proto :qword, :qword ;; int to_loadstring(lua_state *L, const char *string);
lua_pushstring proto :qword, :qword ;; const char *pushstring(lua_State *L, const char *var);
lua_pushboolean proto :qword, :dword ;; void lua_pushboolean(lua_State *L, int b)
lua_isinteger proto :qword, :dword ;; lua_Integer lua_isinteger(lua_State *L, int idx);
lua_tointegerx proto :qword, :dword,:dword ;; lua_Integer lua_tointeger(lua_State *L, int n);
luaL_loadfilex proto :qword, :qword,:dword ;; int luaL_loadfile(lua_State *L, const char *fn, const char *m)
;; void lua_pushcclosure(lua_State *L, lua_CFunction f, int n);
lua_pushccloure proto :qword, :qword, :dword
;; int lua_pcallk(lua_State *L, int argcnt, int results, int errfunc, int context, lua_CFunction k);
lua_pcallk proto :qword, :dword, :dword, :dword, :dword, :dword
 
CLASS lua_class
CMETHOD run
CMETHOD loadstring
CMETHOD loadfile
CMETHOD setglobal
CMETHOD getglobal
CMETHOD getstate
ENDMETHODS
lua_state qword 0
ENDCLASS
 
METHOD lua_class, Init, <VOIDARG>, <>
mov rbx, thisPtr
assume rbx:ptr lua_class
invoke luaL_newstate
mov [rbx].lua_state, rax
invoke luaL_openlibs, [rbx].lua_state
.if rax != LUA_OK
invoke printf, CSTR("---> Lua failed to open libs",10)
jmp _ext
.endif
 
_ext:
mov rax, rbx
assume rbx:nothing
ret
ENDMETHOD
;; dopop = pop off the virtual stack.
METHOD lua_class, run, <VOIDARG>, <>, narg:dword, nret:dword, dopop:word
mov rbx, thisPtr
assume rbx:ptr lua_class
invoke lua_pcallk, [rbx].lua_state, narg, nret, 0, 0, 0
.if rax != LUA_OK
invoke printf, CSTR("--> lua_pcallk failed with %i",10), rax
.else
;; In some cases, we want to pop the top off the stack. But not always
;; so, DO_POP or NO_POP depending..
.if dopop == DO_POP
invoke lua_gettop, [rbx].lua_state
not eax
invoke lua_settop, [rbx].lua_state, eax
.endif
.endif
assume rbx:nothing
ret
ENDMETHOD
 
METHOD lua_class, loadstring, <VOIDARG>, <>, s:qword
invoke luaL_loadstring, [thisPtr].lua_class.lua_state, s
ret
ENDMETHOD
 
METHOD lua_class, loadfile, <VOIDARG>, <>, fn:qword
mov rbx, thisPtr
assume rbx:ptr lua_class
invoke luaL_loadfilex, [rbx].lua_class.lua_state, fn, 0
invoke lua_pcallk, [rbx].lua_state, 0, LUA_MULTRET, 0, 0, 0
.if rax == LUA_OK
invoke lua_gettop, [rbx].lua_state
not eax
invoke lua_settop, [rbx].lua_state, eax
.endif
mov rax, 0
assume rbx:nothing
ret
ENDMETHOD
 
;; lua_class.setglobals(qword ArumentVar, qword ArgumentReferenceName, dword LUA_TTYPE)
;; arg = String(char *) or boolean or integer.
;; an = argument reference name - The name used to reference arg1 from Lua code.
;; t = defined type of argument used.
METHOD lua_class, setglobal, <VOIDARG>, <>, arg:qword, an:qword, t:dword
local targ:qword
local ttype:dword
local tan:qword
 
mov rbx, thisPtr
assume rbx:ptr lua_class
mov targ, arg
mov ttype, t
mov tan, an
.if ttype == LUA_TNIL
invoke lua_pushnil, [rbx].lua_state
.elseif ttype == LUA_TBOOL
mov rax, targ
invoke lua_pushboolean, [rbx].lua_state, eax
.elseif ttype == LUA_TSTRING
invoke lua_pushstring, [rbx].lua_state, targ
.elseif ttype == LUA_TFUNC
;; Used for a lua function call.. But I'm lazy so, check the
;; Lua docs for info about that...
.else
;; Assumes it's an Integer type. Lua's integers are int or long sized(set in luaconfig.h).
;; so qword sized variable to be safe.
invoke lua_pushinteger, [rbx].lua_state, targ
.endif
invoke lua_setglobal, [rbx].lua_state, tan
assume rbx:nothing
ret
ENDMETHOD
 
METHOD lua_class, getglobal, <VOIDARG>, <>, gn:qword
invoke lua_getglobal, [thisPtr].lua_class.lua_state, gn
ret
ENDMETHOD
METHOD lua_class, getstate, <VOIDARG>, <>
mov rax, [thisPtr].lua_class.lua_state
ret
ENDMETHOD
 
METHOD lua_class, Destroy, <VOIDARG>, <>
mov rbx, thisPtr
assume rbx:ptr lua_class
.if [rbx].lua_state != 0
invoke lua_close, [rbx].lua_state
.endif
assume rbx:nothing
ret
ENDMETHOD
 
endif ;; __LUA_CLASS__
 
.data
d1 dq 1342
d2 dq 1551
pFile db "addition.lua",0
 
.code
main proc
local lvm:ptr lua_class
local state:qword
 
invoke printf, CSTR("-> Attempting to init Lua...",10)
mov lvm, _NEW(lua_class)
lvm->getstate()
mov state, rax
invoke printf, CSTR("-> LVM started, Using loadstring..",10)
lvm->loadstring(CSTR("print('---> Goodbye, world from Lua..')"))
lvm->run(0,0, DO_POP)
lvm->setglobal(CSTR("A string that's global"), CSTR("teststr"), LUA_TSTRING)
lvm->setglobal(12, CSTR("numb"), LUA_TNONE)
lvm->loadstring(CSTR("print('---> Global str: ' .. teststr .. '\n---> Global int: ' .. numb)"))
lvm->run(0, 0, DO_POP)
invoke printf, CSTR("-> Loading lua file...",10)
lea rax, pFile
lvm->loadfile(rax)
.if rax != LUA_OK
invoke printf, CSTR("-> Failed loadfile, returned with: %i",10), rax
jmp _ext
.endif
lvm->getglobal(CSTR("addition"))
.if rax != LUA_TFUNC
invoke printf, CSTR("-> Global wasn't a function",10,"-> Type retruned is: %d",10), rax
jmp _ext
.endif
;; We're just pushing the ints onto the Virtual stack for arguments
invoke lua_pushinteger, state, d1
invoke lua_pushinteger, state, d2
lvm->run(2,1,NO_POP)
.if rax == LUA_OK
invoke lua_isinteger, state, -1
.if rax != 1
invoke printf, CSTR("-> Value is NOT an integer..",10)
jmp _ext
.endif
invoke lua_tointegerx, state, -1, 0
push rax
;; Set the top of the virtual stack to our return value..
invoke lua_settop, state, 1
pop rax
invoke printf, CSTR("-> Return from lua func: %i",10), eax
.else
invoke printf, CSTR("-> lvm->run() failed to call func returned: %i",10), rax
.endif
_ext:
_DELETE(lvm)
mov rax, 0
invoke exit, 0
main endp
 
end
</syntaxhighlight>
Addition.lua
<syntaxhighlight lang="lua">
function addition(a, b)
print('---> Lua calc: ' .. a .. ' + ' .. b .. ' = ' .. a+b)
return a + b
end
</syntaxhighlight>
{{out}}
<pre>
-> Attempting to init Lua...
-> LVM started, Using loadstring..
---> Goodbye, world from Lua..
---> Global str: A string that's global
---> Global int: 12
-> Loading lua file...
---> Lua calc: 1342 + 1551 = 2893
-> Return from lua func: 2893
</pre>
===NASM===
{{trans|Wren}}
So yeah. This inits Wrens VM in Assembly to call strdup in C. Now PIE(Position independent executable) compliant.
<syntaxhighlight lang="asm">
;; libc stuff..
extern printf
extern exit
extern malloc
extern free
extern fopen
extern fclose
extern fread
extern fseek
extern ftell
extern rewind
 
;; Wren stuff..
extern wrenNewVM
extern wrenInterpret
extern wrenFreeVM
extern wrenGetSlotString
extern wrenSetSlotString
extern wrenInitConfiguration
 
%define WREN_RESULT_SUCCESS 0
%define WREN_RESULT_COMPILE_ERROR 1
%define WREN_RESULT_RUNTIME_ERROR 2
 
;; Stuff...
extern C_strdup
 
;; time saver 'macros' for PIC(mmm, PIE..)
;; These Macros basically end up being exactly what they look
;; like in code, there's very little preprocessing in NASM,
;; unlike M/UASM's macro systems.(Still more than Gas doe..)
%macro xlea 2
lea %1, [rel %2]
%endmacro
 
%macro xcall 1
call [rel %1 wrt ..got]
%endmacro
 
section .bss
wrenConfig resb 84
wrenVM resq 1
 
section .rodata
szmsg db "--> Starting and configuring WrenVM",10,0
sznoargs db "--> ! No args passed. Supply a filename.",10,0
sznofile db "--> ! Invaild file passed.",10,0
szothererr db "--> ! Wren Error, check script...",10,0
szmod db "main",0
pfmt db "%s",0
szread db "r",0 ;; Why does this have to be a string? Seriously.
 
;; Let this freakshow begin..
section .text
global main
 
main:
push rbp
mov rbp, rsp
sub rsp, 16
cmp edi, 1 ;; argc
jle _main_noargs ;; if(argc <= 1)
mov rax, qword [rsi+1*8] ;; argv[1] - dun dun dunnnn
mov qword [rbp-8], rax
xlea rdi, szmsg
xcall printf
xlea rdi, wrenConfig
xcall wrenInitConfiguration
xlea rax, wrenConfig
xlea rbx, bindfn
mov qword [rax+24], rbx ;; wrenconfig.WrenBindForeignFn
xlea rbx, writefn
mov qword [rax+40], rbx ;; wrenconfig.WrenWriteFn
xlea rbx, errfn
mov qword [rax+48], rbx ;; wrenconfig.WrenErrorFn
xlea rdi, wrenConfig
xcall wrenNewVM
mov [rel wrenVM], rax
mov rdi, qword [rbp-8]
call srcread
mov qword [rbp-16], rax ;; char *wrenScript;
mov rdx, qword [rbp-16]
xlea rsi, szmod
mov esi, 0
mov rdi, [rel wrenVM]
xcall wrenInterpret
cmp rax, WREN_RESULT_SUCCESS
jg _main_noargs
 
jmp _main_exit ;; Let's gtfo of dodge.
_main_noargs:
xlea rdi, sznoargs
xcall printf
 
;; At this point we should free the mem but
;; the program ends so who gives a ....
_main_exit:
add rsp, 16
pop rbp
xor rdi, rdi
xcall exit
ret
 
;; We only care about the file name once, So.. No keepy keepy.
srcread:
push rbp
mov rbp, rsp
sub rsp, 32
xlea rsi,szread
xcall fopen
cmp rax, 0
jle _srcread_nofile
mov qword [rbp-8], rax ;; file handle.
mov edx, 2 ;; SEEK_END
mov esi, 0
mov rdi, qword [rbp-8]
xcall fseek
mov rdi, qword [rbp-8]
xcall ftell
mov qword [rbp-16], rax
mov rdi, qword [rbp-8]
xcall rewind
mov rax, qword [rbp-16]
add rax, 1
mov rdi, rax
xcall malloc
mov qword [rbp-24], rax
mov rcx, qword [rbp-8] ;; file handle
mov rdx, qword [rbp-16] ;; size
mov esi, 1
mov rdi, qword [rbp-24] ;; buffer
xcall fread
mov rdi, qword [rbp-8]
xcall fclose
mov rcx, qword [rbp-16]
mov rax, qword [rbp-24]
add rax, rcx
mov byte [rax], 0
jmp _srcread_exit
 
_srcread_nofile:
xlea rdi, sznofile
xcall printf
 
_srcread_exit:
mov rax, qword [rbp-24]
add rsp, 32
pop rbp
ret
 
;; Just prints whatever's given to it's one argument.
writefn:
push rbp
mov rbp, rsp
xlea rdi, pfmt
xcall printf
pop rbp
ret
 
errfn:
push rbp
mov rbp, rsp
xlea rdi, szothererr
xcall printf
pop rbp
ret
 
;; Still to lazy to do those if checks... -.-
;; I'll do it properly one day, I promise. :]
bindfn:
push rbp
mov rbp, rsp
xlea rax, C_strdup
pop rbp
ret
 
</syntaxhighlight>
strdup.wren
<syntaxhighlight lang="wren">
class C {
foreign static strdup(s)
}
var s = "Goodbye, World!"
System.print(C.strdup(s))
</syntaxhighlight>
strdup.c
<syntaxhighlight lang="c">
void free( void* ptr );
char * strdup( const char *str1 );
 
typedef struct WrenVM WrenVM;
const char* wrenGetSlotString(WrenVM* vm, int slot);
void wrenSetSlotString(WrenVM* vm, int slot, const char* text);
 
void C_strdup(WrenVM* vm) {
const char *s = wrenGetSlotString(vm, 1);
char *t = strdup(s);
wrenSetSlotString(vm, 0, t);
free(t);
}
</syntaxhighlight>
{{out}}
<pre>
--> Starting and configuring WrenVM
Goodbye, World!
</pre>
=={{header|Zig}}==
<syntaxhighlight lang="zig">const std = @import("std");
const c = @cImport({
@cInclude("stdlib.h"); // `free`
@cInclude("string.h"); // `strdup`
});
 
pub fn main() !void {
const string = "Hello World!";
var copy = c.strdup(string);
 
try std.io.getStdOut().writer().print("{s}\n", .{copy});
c.free(copy);
}</syntaxhighlight>
=={{header|zkl}}==
In my opinion, FFIs are very problematic and it is better, if you really need external functionality, to spend the effort to write a glue library. Certainly a lot more work. And it only works for C or C++.
Line 2,010 ⟶ 3,490:
 
flf.c:
<langsyntaxhighlight lang="c">//-*-c-*-
// flf.c, Call a foreign-language function
 
Line 2,045 ⟶ 3,525:
}
return methodCreate(Void,0,zkl_strlen,vm);
}</langsyntaxhighlight>
In use on Linux:
{{out}}
Line 2,060 ⟶ 3,540:
3
</pre>
{{omit from|360 Assembly|A CPU only understands its own machine language. So no assembly language can do this.}}
 
{{omit from|6502 Assembly}}
 
{{omit from|8051 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|AArch64 Assembly}}
{{omit from|ARM Assembly}}
{{omit from|Batch File|Can only execute other programs but cannot call arbitrary functions elsewhere.}}
{{omit from|GUISS}}
{{omit from|M4}}
{{omit from|MIPS Assembly}}
{{omit from|ML/I}}
{{omit from|Order|Doesn't allow to call functions from other languages.}}
Line 2,071 ⟶ 3,558:
{{omit from|TI-89 BASIC|Does not have a standard FFI.}}
{{omit from|Unlambda|Doesn't allow to call functions from other languages.}}
{{omit from|x86 Assembly}}
{{omit from|Z80 Assembly}}
23

edits