---
title: "ForeignFunctionLoad"
language: "en"
type: "Symbol"
summary: "ForeignFunctionLoad[lib, fun, {argtype1, argtype2, ...} -> rettype] loads the function fun with the specified argument and output types from the library lib. ForeignFunctionLoad[ptr, {argtype1, argtype2, ...} -> rettype] creates a foreign function from the function pointer ptr."
keywords: 
- ffi
- foreign function interface
- dynamic library
- shared library
- linking
- external languages
- external library
- C
- C++
- foreign function load
canonical_url: "https://reference.wolfram.com/language/ref/ForeignFunctionLoad.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "C/C++ Language Interface"
    link: "https://reference.wolfram.com/language/guide/CLanguageInterface.en.md"
  - 
    title: "Calling External Programs"
    link: "https://reference.wolfram.com/language/guide/CallingExternalPrograms.en.md"
  - 
    title: "Foreign Function Interface"
    link: "https://reference.wolfram.com/language/guide/ForeignFunctionInterface.en.md"
  - 
    title: "External Operations"
    link: "https://reference.wolfram.com/language/guide/ExternalOperations.en.md"
related_functions: 
  - 
    title: "ForeignFunction"
    link: "https://reference.wolfram.com/language/ref/ForeignFunction.en.md"
  - 
    title: "ForeignPointerLookup"
    link: "https://reference.wolfram.com/language/ref/ForeignPointerLookup.en.md"
  - 
    title: "FindLibrary"
    link: "https://reference.wolfram.com/language/ref/FindLibrary.en.md"
  - 
    title: "RawMemoryAllocate"
    link: "https://reference.wolfram.com/language/ref/RawMemoryAllocate.en.md"
  - 
    title: "RawMemoryRead"
    link: "https://reference.wolfram.com/language/ref/RawMemoryRead.en.md"
  - 
    title: "RawMemoryWrite"
    link: "https://reference.wolfram.com/language/ref/RawMemoryWrite.en.md"
  - 
    title: "RawMemoryImport"
    link: "https://reference.wolfram.com/language/ref/RawMemoryImport.en.md"
  - 
    title: "RawMemoryExport"
    link: "https://reference.wolfram.com/language/ref/RawMemoryExport.en.md"
  - 
    title: "RawPointer"
    link: "https://reference.wolfram.com/language/ref/RawPointer.en.md"
related_tutorials: 
  - 
    title: "Foreign Functions"
    link: "https://reference.wolfram.com/language/tutorial/ForeignFunctions.en.md"
---
[EXPERIMENTAL]

# ForeignFunctionLoad
⚠ *Unsupported in Public Cloud*

ForeignFunctionLoad[lib, fun, {argtype1, argtype2, …} -> rettype] loads the function fun with the specified argument and output types from the library lib.

ForeignFunctionLoad[ptr, {argtype1, argtype2, …} -> rettype] creates a foreign function from the function pointer ptr.

## Details

* ``ForeignFunctionLoad`` returns the ``ForeignFunction`` object.

* ``lib`` is resolved with ``FindLibrary``.

* ``lib`` must be a C-compatible dynamic library.

* Supported types generally align with those supported by the [Wolfram Compiler](https://reference.wolfram.com/language/guide/CompiledTypes.en.md).

* Possible argument and return types and their corresponding C types include:

|                     |                            |                                  |
| ------------------- | -------------------------- | -------------------------------- |
| "UnsignedInteger8"  | uint8\_t                   | unsigned 8-bit integer           |
| "Integer8"          | int8\_t                    | signed 8-bit integer             |
| "UnsignedInteger16" | uint16\_t                  | unsigned 16-bit integer          |
| "Integer16"         | int16\_t                   | signed 16-bit integer            |
| "UnsignedInteger32" | uint32\_t                  | unsigned 32-bit integer          |
| "Integer32"         | int32\_t                   | signed 32-bit integer            |
| "UnsignedInteger64" | uint64\_t                  | unsigned 64-bit integer          |
| "Integer64"         | int64\_t                   | signed 64-bit integer            |
| "CUnsignedChar"     | unsigned char              | C-compatible unsigned char       |
| "CSignedChar"       | signed char                | C-compatible signed char         |
| "CUnsignedShort"    | unsigned short             | C-compatible unsigned short      |
| "CShort"            | short                      | C-compatible short               |
| "CUnsignedInt"      | unsigned int               | C-compatible unsigned int        |
| "CInt"              | int                        | C-compatible int                 |
| "CUnsignedLong"     | unsigned long              | C-compatible unsigned long       |
| "CLong"             | long                       | C-compatible long                |
| "CSizeT"            | size\_t                    | C-compatible size\_t             |
| "CFloat"            | float                      | C-compatible float               |
| "CDouble"           | double                     | C-compatible double              |
| "OpaqueRawPointer"  | void\*                     | opaque pointer                   |
| "RawPointer"::[t]   | t *                        | typed pointer                    |
| {ty1, ty2, …}       | struct {ty1 f1; ty2 f2; …} | struct or product type           |
| "Void"              | void                       | no output (only in output types) |

* Struct or product types can also be written as ``"ListTuple"::[ty1, ty2, …]``.

* In ``ForeignFunctionLoad[ptr, …]``, ``ptr`` must be an ``OpaqueRawPointer`` pointing to a valid function in a library.

## Examples (9)

### Basic Examples (1)

Load a function from a library:

```wl
In[1]:= addone = ForeignFunctionLoad["compilerDemoBase", "addone", {"CInt"} -> "CInt"]

Out[1]=
ForeignFunction["/Applications/W14.1.0-dev.app/Contents/SystemFiles/Links/LibraryLink/LibraryResour\
ces/MacOSX-ARM64/compilerDemoBase.dylib", "addone", DataStructure["RawForeignFunction", 
  {"FunctionPointer" -> OpaqueRawPointer[4947918356], "Type" -> {"CInt"} -> "CInt"}]]
```

Call the function:

```wl
In[2]:= addone[12]

Out[2]= 13
```

### Scope (2)

``ForeignFunctionLoad`` uses ``FindLibrary`` to locate libraries:

```wl
In[1]:= ForeignFunctionLoad["compilerDemoBase", "addone", {"CInt"} -> "CInt"]

Out[1]=
ForeignFunction["/Applications/W14.1.0-dev.app/Contents/SystemFiles/Links/LibraryLink/LibraryResour\
ces/MacOSX-ARM64/compilerDemoBase.dylib", "addone", DataStructure["RawForeignFunction", 
  {"FunctionPointer" -> OpaqueRawPointer[4947918356], "Type" -> {"CInt"} -> "CInt"}]]
```

Alternatively, find the library once with ``FindLibrary`` and pass it to ``ForeignFunctionLoad`` :

```wl
In[2]:=
lib = FindLibrary["compilerDemoBase"];
ForeignFunctionLoad[lib, "addone", {"CInt"} -> "CInt"]

Out[2]=
ForeignFunction["/Applications/W14.1.0-dev.app/Contents/SystemFiles/Links/LibraryLink/LibraryResour\
ces/MacOSX-ARM64/compilerDemoBase.dylib", "addone", DataStructure["RawForeignFunction", 
  {"FunctionPointer" -> OpaqueRawPointer[4947918356], "Type" -> {"CInt"} -> "CInt"}]]
```

---

Get the pointer to a function in a library:

```wl
In[1]:= funPtr = ForeignPointerLookup["compilerDemoBase", "addone"]

Out[1]= OpaqueRawPointer[4947918356]
```

Load the foreign function by using the function pointer and specifying its type:

```wl
In[2]:= ForeignFunctionLoad[funPtr, {"CInt"} -> "CInt"]

Out[2]=
ForeignFunction[None, None, DataStructure["RawForeignFunction", 
  {"FunctionPointer" -> OpaqueRawPointer[4947918356], "Type" -> {"CInt"} -> "CInt"}]]
```

### Applications (2)

Create a foreign function for the RAND\_bytes function from OpenSSL:

```wl
In[1]:= opensslPath = FileNameJoin[...];

In[2]:= randBytes = ForeignFunctionLoad[opensslPath, "RAND_bytes", {"RawPointer"::["UnsignedInteger8"], "CInt"} -> "CInt"]

Out[2]=
ForeignFunction[
 "/Applications/W14.1.0-dev.app/Contents/SystemFiles/Libraries/MacOSX-ARM64/libcrypto.3.dylib", 
 "RAND_bytes", DataStructure["RawForeignFunction", 
  {"FunctionPointer" -> OpaqueRawPointer[4839290668], 
   "Type" -> {TypeSpecifier["RawPointer"]["UnsignedInteger8"], "CInt"} -> "CInt"}]]
```

Create a buffer into which the random bytes can be written:

```wl
In[3]:= out = RawMemoryAllocate["UnsignedInteger8", 32]

Out[3]=
ManagedObject[RawPointer[4944777984, "UnsignedInteger8"], 
 RawPointer[4944777984, "UnsignedInteger8"], RawMemoryFree]
```

Generate the random bytes by calling RAND\_bytes:

```wl
In[4]:= randBytes[out, 32]

Out[4]= 1
```

Read the output:

```wl
In[5]:= RawMemoryImport[out, {"List", 32}]

Out[5]= {239, 5, 215, 222, 192, 79, 124, 101, 20, 170, 22, 64, 61, 106, 22, 175, 226, 92, 216, 61, 155, 31, 54, 96, 9, 19, 15, 130, 249, 35, 218, 168}
```

Package into a function:

```wl
In[6]:=
generateRandomBytes[len_] := 
	With[{out = RawMemoryAllocate["UnsignedInteger8", len]}, 
	randBytes[out, len];RawMemoryImport[out, {"ByteArray", len}]
	]
```

The foreign function is very efficient:

```wl
In[7]:= RepeatedTiming[generateRandomBytes[10000000];]

Out[7]= {0.0162883, Null}

In[8]:= RepeatedTiming[RandomInteger[{0, 255}, 10000000];]

Out[8]= {0.0580281, Null}
```

---

Implement SHA256 using OpenSSL:

```wl
In[1]:= opensslPath = FileNameJoin[...];

In[2]:= sha256 = ForeignFunctionLoad[opensslPath, "SHA256", {"RawPointer"::["UnsignedInteger8"], "CUnsignedLong", "RawPointer"::["UnsignedInteger8"]} -> "RawPointer"::["UnsignedInteger8"]]

Out[2]=
ForeignFunction[
 "/Applications/W14.1.0-dev.app/Contents/SystemFiles/Libraries/MacOSX-ARM64/libcrypto.3.dylib", 
 "SHA256", DataStructure["RawForeignFunction", {"FunctionPointer" -> OpaqueRawPointer[4839388032], 
   "Type" -> {TypeSpecifier["RawPointer"]["UnsignedInteger8"], "CUnsignedLong", 
      TypeSpecifier["RawPointer"]["UnsignedInteger8"]} -> TypeSpecifier["RawPointer"][
      "UnsignedInteger8"]}]]
```

Create a buffer containing the plaintext to hash:

```wl
In[3]:=
plaintext = "Hello, World!";
plaintextBuf = RawMemoryExport[plaintext]

Out[3]=
ManagedObject[RawPointer[4853847232, "UnsignedInteger8"], 
 RawPointer[4853847232, "UnsignedInteger8"], RawMemoryFree]
```

Create a buffer into which to write the hash:

```wl
In[4]:= ciphertextBuf = RawMemoryAllocate["UnsignedInteger8", 32]

Out[4]=
ManagedObject[RawPointer[4944765088, "UnsignedInteger8"], 
 RawPointer[4944765088, "UnsignedInteger8"], RawMemoryFree]
```

Execute the hash:

```wl
In[5]:= sha256[plaintextBuf, StringLength[plaintext], ciphertextBuf]

Out[5]= RawPointer[4944765088, "UnsignedInteger8"]
```

Read the results from the ciphertext buffer:

```wl
In[6]:= RawMemoryImport[ciphertextBuf, {"List", 32}]

Out[6]= {223, 253, 96, 33, 187, 43, 213, 176, 175, 103, 98, 144, 128, 158, 195, 165, 49, 145, 221, 129, 199, 247, 10, 75, 40, 104, 138, 54, 33, 130, 152, 111}
```

Compare with the built-in function ``Hash`` :

```wl
In[7]:= Normal@Hash[plaintext, "SHA256", "ByteArray"]

Out[7]= {223, 253, 96, 33, 187, 43, 213, 176, 175, 103, 98, 144, 128, 158, 195, 165, 49, 145, 221, 129, 199, 247, 10, 75, 40, 104, 138, 54, 33, 130, 152, 111}
```

Package into a function:

```wl
In[8]:=
generateSHA256[plaintext_] := 
	With[{
	plaintextBuf = RawMemoryExport[plaintext], ciphertextBuf = RawMemoryAllocate["UnsignedInteger8", 32]
	}, 
	sha256[plaintextBuf, StringLength[plaintext], ciphertextBuf];
	RawMemoryImport[ciphertextBuf, {"ByteArray", 32}]
	]
```

The packaged function is very efficient:

```wl
In[9]:= RepeatedTiming[generateSHA256[plaintext]]

Out[9]=
{0.0000533411, ByteArray[{223, 253, 96, 33, 187, 43, 213, 176, 175, 103, 98, 144, 128, 158, 195, 165, 49, 145, 
  221, 129, 199, 247, 10, 75, 40, 104, 138, 54, 33, 130, 152, 111}]}

In[10]:= RepeatedTiming[Hash[plaintext, "SHA256", "ByteArray"]]

Out[10]=
{0.00022481, ByteArray[{223, 253, 96, 33, 187, 43, 213, 176, 175, 103, 98, 144, 128, 158, 195, 165, 49, 145, 
  221, 129, 199, 247, 10, 75, 40, 104, 138, 54, 33, 130, 152, 111}]}
```

### Properties & Relations (1)

``ForeignFunctionLoad`` can generally create callable links to libraries faster than custom links can be compiled:

```wl
In[1]:=
With[{libPath = FindLibrary["compilerDemoBase"]}, 
	RepeatedTiming[addone = ForeignFunctionLoad[libPath, "addone", {"CInt"} -> "CInt"]]
	]

Out[1]=
{0.0000715204, ForeignFunction["/Applications/W14.1.0-dev.app/Contents/SystemFiles/Links/LibraryLink/LibraryResour\
ces/MacOSX-ARM64/compilerDemoBase.dylib", "addone", DataStructure["RawForeignFunction", 
  {"FunctionPointer" -> OpaqueRawPointer[4947918356], "Type" -> {"CInt"} -> "CInt"}]]}

In[2]:=
RepeatedTiming[addoneCf = FunctionCompile[
	LibraryFunctionDeclaration["addone", "compilerDemoBase", {"CInt"} -> "CInt"], 
	Function[Typed[x, "CInt"], LibraryFunction["addone"][x]]
	]]

Out[2]=
{0.136406, CompiledCodeFunction[Association["Signature" -> TypeSpecifier[{"Integer32"} -> "Integer32"], 
  "Input" -> Compile`Program[{LibraryFunctionDeclaration["addone", "compilerDemoBase", 
      {"CInt"} -> "CInt"]}, Function[Typed[x, "CInt"],  ...  -> ByteArray[CompressedData["«4090»"]]], "ExternalLibraryPaths" -> {"compilerDemoBase"}, 
  "orcInstance" -> 4963977568, "orcModuleId" -> 105553132296192], 15799500952, 15799500804, 
 15799500864, 15799500800, "{\"Integer32\"} -> \"Integer32\""]}
```

However, the custom compiled versions can have less overhead:

```wl
In[3]:= RepeatedTiming[addone[10]]

Out[3]= {4.37640380859375`*^-6, 11}

In[4]:= RepeatedTiming[addoneCf[10]]

Out[4]= {2.9474306106567384`*^-7, 11}
```

### Possible Issues (3)

If the library does not exist, a ``Failure`` is returned:

```wl
In[1]:= ForeignFunctionLoad["fakeLibrary", "addone", {"CInt"} -> "CInt"]
```

ForeignFunctionLoad::invlib: Library fakeLibrary not found.

```wl
Out[1]=
Failure["InvalidLibrary", Association["MessageTemplate" :> ForeignFunctionLoad::invlib, 
  "MessageParameters" -> {"fakeLibrary"}, "LibrarySpecification" -> "fakeLibrary", 
  "FindLibraryResult" :> $Failed]]
```

---

If the function does not exist, a ``Failure`` is returned:

```wl
In[1]:= ForeignFunctionLoad["compilerDemoBase", "fakeFunction", {"CInt"} -> "CInt"]
```

ForeignPointerLookup::lookuperr: Failed to lookup symbol in external library with error: dlsym(0x93ea9f60, fakeFunction): symbol not found

```wl
Out[1]=
Failure["FunctionLoad", Association["MessageTemplate" :> ForeignPointerLookup::lookuperr, 
  "MessageParameters" -> {"dlsym(0x93ea9f60, fakeFunction): symbol not found"}, 
  "LibraryError" -> "dlsym(0x93ea9f60, fakeFunction): symbol not found"]]
```

---

``ForeignFunctionLoad`` will return ``\$Failed`` if a type is not supported:

```wl
In[1]:= ForeignFunctionLoad["compilerDemoBase", "addone", {"UnsignedInger18"} -> "CInt"]
```

ForeignFunction::invtype: UnsignedInger18 cannot be used as a foreign function interface type.

```wl
Out[1]= $Failed
```

## See Also

* [`ForeignFunction`](https://reference.wolfram.com/language/ref/ForeignFunction.en.md)
* [`ForeignPointerLookup`](https://reference.wolfram.com/language/ref/ForeignPointerLookup.en.md)
* [`FindLibrary`](https://reference.wolfram.com/language/ref/FindLibrary.en.md)
* [`RawMemoryAllocate`](https://reference.wolfram.com/language/ref/RawMemoryAllocate.en.md)
* [`RawMemoryRead`](https://reference.wolfram.com/language/ref/RawMemoryRead.en.md)
* [`RawMemoryWrite`](https://reference.wolfram.com/language/ref/RawMemoryWrite.en.md)
* [`RawMemoryImport`](https://reference.wolfram.com/language/ref/RawMemoryImport.en.md)
* [`RawMemoryExport`](https://reference.wolfram.com/language/ref/RawMemoryExport.en.md)
* [`RawPointer`](https://reference.wolfram.com/language/ref/RawPointer.en.md)

## Tech Notes

* [Foreign Functions](https://reference.wolfram.com/language/tutorial/ForeignFunctions.en.md)

## Related Guides

* [C/C++ Language Interface](https://reference.wolfram.com/language/guide/CLanguageInterface.en.md)
* [Calling External Programs](https://reference.wolfram.com/language/guide/CallingExternalPrograms.en.md)
* [Foreign Function Interface](https://reference.wolfram.com/language/guide/ForeignFunctionInterface.en.md)
* [External Operations](https://reference.wolfram.com/language/guide/ExternalOperations.en.md)

## History

* [Introduced in 2023 (13.3)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn133.en.md)