# Create a custom @ccall

**URL:** https://discourse.julialang.org/t/create-a-custom-ccall/117243
**Category:** New to Julia
**Tags:** ccall, macros
**Created:** [July 19, 2024, 2:55pm UTC](https://discourse.julialang.org/t/create-a-custom-ccall/117243 "2024-07-19T14:55:45Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)
#### Post date: [July 19, 2024, 2:55pm UTC](https://discourse.julialang.org/t/create-a-custom-ccall/117243/1 "2024-07-19T14:55:45Z")

</div>

I am trying to create a macro that replaces the @ccall in my code.  
My idea is to create something like this:

```julia
macro my_ccall(arg)
     custom_function_before_ccall()
     @ccall arg
end

```

I am having trouble with the type of the argument “arg”. I want it essentially to do just syntax replacement (like the define in C). Is it possible ?  
Thanks in advance !

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [July 20, 2024, 8:40am UTC](https://discourse.julialang.org/t/create-a-custom-ccall/117243/2 "2024-07-20T08:40:21Z")

</div>

Not sure this is the type of answer you’re looking for, but you could simply adapt the implementation of [`@ccall`](https://github.com/JuliaLang/julia/blob/3290904379766c37796016180993c19c34c8c31a/base/c.jl#L408), leaving the difficult parts to the existing methods `ccall_macro_lower` and `ccall_macro_parse`:

```julia
julia> import Base: ccall_macro_lower, ccall_macro_parse

julia> macro my_ccall(expr)
           println("Hello from my custom ccall!")
           return ccall_macro_lower(:ccall, ccall_macro_parse(expr)...)
       end
@my_ccall (macro with 1 method)

julia> @my_ccall clock()::Int32
Hello from my custom ccall!
274138

```

EDIT: Like in Patrick’s approach below, it’s in general probably better to put the `println` (`custom_function_before_ccall()`) inside the returned expression:

```julia
julia> import Base: ccall_macro_lower, ccall_macro_parse

julia> custom_function_before_ccall() = println("Hello")
custom_function_before_ccall (generic function with 1 method)

julia> macro my_ccall(expr)
            ret_expr = ccall_macro_lower(:ccall, ccall_macro_parse(expr)...)
            return :(custom_function_before_ccall(); $ret_expr)
       end
@my_ccall (macro with 1 method)

julia> @my_ccall clock()::Int32
Hello
67218

```

Patrick’s approach is also a bit simpler, so you should probably just use that 🙂 .

---

<div class="post-metadata">

### Author: ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)
#### Post date: [July 20, 2024, 12:06pm UTC](https://discourse.julialang.org/t/create-a-custom-ccall/117243/3 "2024-07-20T12:06:24Z")

</div>

A macro typically should return an Expr. Depending on what you want to do exactly, something like

```julia
macro my_ccall(arg)
    quote
        custom_function_before_ccall()
        @ccall $arg
    end |> esc
end

```

should work. You probably want to apply a more nuanced escaping than that, but that depends on your specific situation.

Edit: Incorrect parentheses removed

---

<div class="post-metadata">

### Author: ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)
#### Post date: [July 22, 2024, 9:06am UTC](https://discourse.julialang.org/t/create-a-custom-ccall/117243/4 "2024-07-22T09:06:49Z")

</div>

Thanks for your answers !  
Actually although Patrick’s solution is more elegant, it did not work for me. I should have been more precise in my initial post: I also want to run function after the ccall. I think that maybe using @ccall that expands to `return ccall_macro_lower(:ccall, ccall_macro_parse(expr)...)` will cause the lines following the ccall not to be executed ? Does this make any sense ?

What worked for me is the following:

```julia
 macro my_ccall(expr)
            custom_function_before_ccall()
            ret_expr = ccall_macro_lower(:ccall, ccall_macro_parse(expr)...)
            custom_function_after_ccall()
            return ret_expr
end

```

I also tried

```julia
 macro my_ccall(expr)
       quote
            custom_function_before_ccall()
            ret_expr = @ccall($expr)
            custom_function_after_ccall()
            return ret_expr
     end |> esc
end

```

and

```julia
 macro my_ccall(expr)
       quote
            custom_function_before_ccall()
            ret_expr = ccall_macro_lower(:ccall, ccall_macro_parse($expr)...)
            custom_function_after_ccall()
            return ret_expr
     end |> esc
end

```

with no success

---

<div class="post-metadata">

### Author: ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)
#### Post date: [July 22, 2024, 12:20pm UTC](https://discourse.julialang.org/t/create-a-custom-ccall/117243/5 "2024-07-22T12:20:54Z")

</div>

This works for me:

```julia
macro my_ccall(arg)
    result = gensym() # Do not conflict with identifiers from the call site even with the brute-force escaping used below
    return quote
        custom_function_before_ccall()
        $result = @ccall $arg
        custom_function_after_ccall()
        $result # Set return value of quote block
    end |> esc
end
custom_function_before_ccall() = println("before")
custom_function_after_ccall() = println("after")
@my_ccall clock()::Int

```

Note that on the REPL `after` is print before the result of `clock()` because the REPL does the printing of the return value when the macro is done. This is only an “observer” problem, the execution order is correct.

I had an additional pair of parentheses in the `@ccall`, because I forgot, that `@ccall` is special syntax and not a usual macro. I am sorry about that.

You had a mix of `expr` and `arg` which probably did not work.

Please note, that the solutions are totally different, which you will not observe in trivial cases.

In the solution proposed by me, everything is returned by the macro, so the macro is just rewriting code. The function `custom_function_*_ccall` are returned by the macro as code (`Expr`) and run during runtime. So if you put `@my_ccall clock()::Int` into a function, the functions `custom_function_*_ccall` are called whenever your function is called.

In your solution, the functions are executed during macro execution time. As your macro only returns a value, `custom_function_*_ccall` are not called when your function containing `@my_ccall clock()::Int` is called.

When working with macros, you have the chance to sneak something into the early startup phase of your program (depending on when your file is included, imported or used, this can be also quite late). You always need to think whether you really want to do something now or whether you just want to change the code at the macro’s caller to do something later.

So the question really is: What do you want? If this is a one-time initialization, go ahead with your approach executing the functions during macro execution (but keep in mind that macro execution is generally done during module precompilation).  
If you just want to save typing and call the functions whenever your function is called, you should switch to the approach suggested by me (or something similar returning the function calls inside an `Expr`).
