# Wrapping a C library | Where to start?

**URL:** https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658
**Category:** General Usage
**Tags:** package, ccall, cwrap, c, clang
**Created:** [November 17, 2021, 1:26pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658 "2021-11-17T13:26:12Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)
#### Post date: [November 17, 2021, 1:26pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/1 "2021-11-17T13:26:12Z")

</div>

Hi!

I want to use a few functions of a `dll` file from Julia and I want to wrap them in a package. The `dll`s I want to use are for talking to some motion controllers (The `dll`s in question can be found on [thorlabs.com](https://www.thorlabs.com/software_pages/ViewSoftwarePage.cfm?Code=Motion_Control&viewtab=0). There are also `.h` files included.

My first problem is to actually write the wrapping module. From the REPL (and also by `include`ing a file) I can do

```julia
julia> using Libdl
julia> dlopen("Thorlabs.MotionControl.KCube.Solenoid.dll")
Ptr{Nothing} @0x00007ff8be9b0000

```

with the `dll` file in the working directory. I am also able to call the functions via `ccall`.

However, if I try to access this `dll` file in a module (or its tests) I get an error:

```julia
could not load library "Thorlabs.MotionControl.KCube.Solenoid.dll"
  The specified module could not be found.
  Stacktrace:
    [1] open(serial_number::String)
      @ KCubeSolenoid C:\Users\Admin\.julia\dev\KCubeSolenoid\src\KCubeSolenoid.jl:9
    [2] macro expansion
      @ show.jl:955 [inlined]
    [3] macro expansion
      @ C:\Users\Admin\.julia\dev\KCubeSolenoid\test\runtests.jl:9 [inlined]
    [4] macro expansion
      @ C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Test\src\Test.jl:1151 [inlined]
    [5] top-level scope
      @ C:\Users\Admin\.julia\dev\KCubeSolenoid\test\runtests.jl:7
    [6] include(fname::String)
      @ Base.MainInclude .\client.jl:444
    [7] top-level scope
      @ none:6
    [8] eval
      @ .\boot.jl:360 [inlined]
    [9] exec_options(opts::Base.JLOptions)
      @ Base .\client.jl:261
   [10] _start()
      @ Base .\client.jl:485

```

So I guess the `dll` is in the wrong location? How would I actually go about and structure the wrapping package? Where should the `dll` file go?

I briefly tried to wrap the library with `Clang.jl` but it failed parsing the header file. Are there any tutorials on how to write a wrapper for a simple `dll` library and ship that as a Julia package?

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [November 17, 2021, 1:36pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/2 "2021-11-17T13:36:56Z")

</div>

> [@MLackner](#):
>
> However, if I try to access this `dll` file in a module (or its tests) I get an error:

If you don’t want to struggle, the argument to `dlopen` should be an absolute path (or a relative path to an absolute path like [`@ __DIR__ `](https://docs.julialang.org/en/v1/base/base/#Base.@ __DIR__ )). [`Libdl.find_library`](https://docs.julialang.org/en/v1/stdlib/Libdl/#Base.Libc.Libdl.find_library) might also be useful.

---

<div class="post-metadata">

### Author: ![krrutkow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krrutkow/32/9138_2.png) [@krrutkow](https://discourse.julialang.org/u/krrutkow)
#### Post date: [November 17, 2021, 10:29pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/3 "2021-11-17T22:29:22Z")

</div>

> I briefly tried to wrap the library with `Clang.jl` but it failed parsing the header file.

You may also want to look at using [CBinding.jl](https://github.com/analytech-solutions/CBinding.jl) to create the bindings for you. If you are somewhat comfortable with C development against the library, then using CBinding should be very familiar. I have used it to create bindings for just about everything (GLibC, GLib, GTK, Linux headers) with very little effort:

```julia
module MyLib
  using CBinding
  c`-I/include/path -L/lib/path -lmylib`
  c"""
    #include <mylib.h>
  """ji
end

```

A more sophisticated [example](https://github.com/analytech-solutions/ExamplesUsingCBinding.jl/blob/master/test/SDL2.jl)

---

<div class="post-metadata">

### Author: ![vfonov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vfonov/32/31828_2.png) [@vfonov](https://discourse.julialang.org/u/vfonov)
#### Post date: [December 20, 2021, 5:24pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/4 "2021-12-20T17:24:51Z")

</div>

Hello,

I am new with Julia, and decided to start by porting one of the File IO libraries that I use in my work a lot.  
So far I was successfully able to make a \_jll package for the library + basic wrapper using CBinding.jl

Is there a more complete examples on wrapping C libraries ? In particular, I need to deal with automatically releasing resources allocated in C code (i.e calling destructor). And passing multidimensional arrays of different types.

---

<div class="post-metadata">

### Author: ![krrutkow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krrutkow/32/9138_2.png) [@krrutkow](https://discourse.julialang.org/u/krrutkow)
#### Post date: [December 20, 2021, 6:21pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/5 "2021-12-20T18:21:02Z")

</div>

Unfortunately, there is no simple answer… The design of the C library and the desired design/usage of the Julia package wrapping it all play a part in that, so you will have to find examples from packages across the Julia ecosystem that utilize a C library that seem to fit your situation. Resource management is a good example of the various approaches you will see used:

For short-lifetime objects, something like this:

```julia
x = nothing
try
  x = alloc()
  use(x)
finally
  isnothing(x) || free(x)
end

```

Which can be wrapped with a function:

```julia
function with_resource(func::Function)
  x = nothing
  try
    x = alloc()
    func(x)
  finally
    isnothing(x) || free(x)
  end
end
# then used with
with_resource(x -> use(x))
# or
with_resource() do x
  use(x)
end

```

Or for objects that can be cleaned up at the leisure of the GC, something like:

```julia
struct Resource
  x::Ref

  function Resource()
    ret = new(Ref(alloc()))
    finalizer(x -> free(x[]), ret.x)
    return ret
  end
end

```

For library setup before the API can be called, you might use something like this:

```julia
module Example
  x = nothing
  function __init__ ()
    global x = alloc()
  end
end

```

There are probably many more options for multi-dimensional arrays, depending on how they are arranged in memory, etc.

---

<div class="post-metadata">

### Author: ![vfonov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vfonov/32/31828_2.png) [@vfonov](https://discourse.julialang.org/u/vfonov)
#### Post date: [December 20, 2021, 7:25pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/6 "2021-12-20T19:25:47Z")

</div>

thank you, these examples are already very useful.

---

<div class="post-metadata">

### Author: ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)
#### Post date: [March 15, 2022, 4:46pm UTC](https://discourse.julialang.org/t/wrapping-a-c-library-where-to-start/71658/7 "2022-03-15T16:46:41Z")

</div>

Okay… I finally had time to play around with this a little more. Thanks for all the suggestions!

I tried wrapping the library manually, with `Clang.jl`, and `CBinding.jl` but in both cases I seem to have trouble parsing the header files.

My case: I have a header `Thorlabs.MotionControl.KCube.Solenoid.h`. I downloaded that one from the link in the opening post. I now want to write a wrapper for this library.

### Let’s start with my manual attempt

The first thing I tried (and failed at 😕) was wrapping the `SC_Open`, and `SC_Close` functions. The relevant part of the header file is this:

```c
	/// <summary> Open the device for communications. </summary>
	/// <param name="serialNo">	The serial no of the device to be connected. </param>
	/// <returns> The error code (see \ref C_DLL_ERRORCODES_page "Error Codes") or zero if successful. </returns>
    /// \include CodeSnippet_connection1.cpp
	/// <seealso cref="SC_Close(char const * serialNo)" />
	KCUBESOLENOID_API short __cdecl SC_Open(char const * serialNo);

	/// <summary> Disconnect and close the device. </summary>
	/// <param name="serialNo">	The serial no of the device to be disconnected. </param>
    /// \include CodeSnippet_connection1.cpp
	/// <seealso cref="SC_Open(char const * serialNo)" />
	KCUBESOLENOID_API void __cdecl SC_Close(char const * serialNo);

```

My attempt of wrapping these:

```julia-auto
libfile = "C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.KCube.Solenoid.dll"
@assert isfile(libfile)
solenoid = Libdl.dlopen(libfile)

function open(serialnumber)
    sym = Libdl.dlsym(solenoid, :SC_Open)
    ccall(sym, cdecl, Int16, (Ref{String}, ), serialnumber)
end

function close(serialnumber)
    sym = Libdl.dlsym(solenoid, :SC_Close)
    ccall(sym, cdecl, Cvoid, (Ref{String}, ), serialnumber)
end

serialnumber = Ref{String}("68210439")

begin
    @show open(serialnumber)
    close(serialnumber)
end

```

This fails with `open(serialnumber)` returning an error code that the device was not found (although connected and working with other software). I guess the problem is in the input argument types in the `ccall` function. I am not sure `Ref{String}` is the correct Julia type for `char const * serialNo`.

### `Clang.jl`

To me it seemed a good idea to circumvent this smoothness of my brain by automagically wrapping the header file with `Clang.jl`. I don’t really have an idea what I’m doing here so I created a `generator.toml` file with the following content

```toml
[general]
library_name = "Thorlabs.MotionControl.KCube.Solenoid"
output_file_path = "./Solenoid.jl"
module_name = "Solenoid"
export_symbol_prefixes = ["SC", "FT", "MOT", "TLI"]

```

and a script

```julia-auto
using Clang.Generators

cd(@ __DIR__ )

include_dir = normpath("C:/Program Files/Thorlabs/Kinesis/")
kinesis_dir = include_dir

options = load_options(joinpath(@ __DIR__ , "generator.toml"))

args = get_default_args()
push!(args, "-I$include_dir")

headers = [joinpath(kinesis_dir, "Thorlabs.MotionControl.KCube.Solenoid.h")]

ctx = create_context(headers, args, options)

build!(ctx)

```

which closely follows the tutorial on the `Clang.jl` GitHub page. However, `Clang.jl` seems to have problems parsing the headers. `create_context` does not throw an error but I get these messages:

```julia-auto
[ Info: Parsing headers...
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\ia32intrin.h:95:1: error: definition of builtin function '__rdtsc'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\xmmintrin.h:792:1: error: definition of builtin function '_mm_getcsr'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\xmmintrin.h:824:1: error: definition of builtin function '_mm_setcsr'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\xmmintrin.h:1216:1: error: definition of builtin function '_mm_sfence'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\xmmintrin.h:1225:1: error: definition of builtin function '_mm_pause'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\emmintrin.h:1457:1: error: definition of builtin function '_mm_clflush'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\emmintrin.h:1463:1: error: definition of builtin function '_mm_lfence'
C:\Users\MG222\.julia\artifacts\217a1339fc81b7388fc8af3fc8a05bca7b7ced19\lib\gcc\x86_64-w64-mingw32\4.8.5\include\emmintrin.h:1469:1: error: definition of builtin function '_mm_mfence'
C:\Program Files\Thorlabs\Kinesis\Thorlabs.MotionControl.KCube.Solenoid.h:33:8: error: expected identifier or '('
Context(...)

```

From my research on the web I came to the conclusion (which I do not fully understand) that these headers contain function definitions which are part of the `gcc` compiler but are not recognized by `clang`???

So, because the header file is not parsed correctly I only get this output printed in `Solenoid.jl`:

```julia
module Solenoid

using CEnum

const KCUBESOLENOID_API = __declspec(dllimport)

# exports
const PREFIXES = ["SC", "FT", "MOT", "TLI"]
for name in names(@ __MODULE__ ; all=true), prefix in PREFIXES
    if startswith(string(name), prefix)
        @eval export $name
    end
end

end # module

```

Is there a way to ignore certain `include` statements or does everything have to be parsed in order to generate Julia bindings?

### `CBinding.jl`

My naïve first try was

```julia-auto
using CBinding

libpath = "C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.KCube.Solenoid.dll"

c`$([
    "-std=c99",
    "-Wall",
    "-DGO_FAST=1",
    "-L$(libpath)", "-Thorlabs.MotionControl.KCube.Solenoid"
])`

c"""
#include <C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.KCube.Solenoid.h>
"""ji

```

which resulted in

```julia-auto
Error: C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.KCube.Solenoid.h:14:10: fatal error: 'OaIdl.h' file not found

```

The `OaIdl.h` file seems to be part of the Windows SDK. So I installed that and added the path to this specific header file to the compiler context. This continued with numerous other header files which I had to manually include (I guess that’s not the way to do it) and changing the target in the compiler context to `"--target=stable-x86_64-pc-windows-msvc"`. Only to end up with a parsing error that I am not able to resolve:

```julia-auto
┌ Error: C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\corecrt.h:609:32: error: typedef redefinition with different types ('__crt_locale_pointers *' (aka 'struct__crt_locale_pointers *') vs 'struct localeinfo_struct *')
└ @ CBinding C:\Users\MG222\.julia\packages\CBinding\kBUap\src\context.jl:377
┌ Error: C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.KCube.Solenoid.h:33:8: error: expected identifier or '('
└ @ CBinding C:\Users\MG222\.julia\packages\CBinding\kBUap\src\context.jl:377
ERROR: LoadError: Errors parsing C code

```

### …

So any suggestions and ideas on how to resolve my problems with any of the three approaches are highly welcome 🙂.
