Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Embedding raw C++

jank has a special cpp/raw form which accepts a single string containing literal C++ code. This can be used for bringing in pretty much anything. For example, we can use this to include header files (though prefer the clojure.core/include macro for this).

(cpp/raw "#include <fstream>")

jank will always compile the included C++ source in a global scope, even if you put the cpp/raw form within a nested scope, such as within a function or a let. For example, this code will have the same effect, even if this function is never called.

(defn foo []
  (cpp/raw "#include <fstream>"))

The cpp/raw form always evaluates to nil. At runtime, foo will do nothing but return nil, since the JIT compilation is where the effect of cpp/raw actually happens.

Note

Unlike in C++, you will not need to #include in every source file, since the global C++ environment is affected by each file inclusion. This is simply due to how Clang’s JIT compilation works. However, this means you should be even more careful with how much you include and how name collisions might happen within your jank projects.

A helpful idiom

Hopefully this becomes a less common idiom simply by not being needed, but for now it’s common enough. If you run into issues trying to access a member, call a function, etc using normal C++ interop, you can write a wrapper in cpp/raw which will do the trick. For example, let’s say we have the following code.

(let [s (cpp/std.string)
      ; Let's say that this interop call isn't compiling correctly, due to a
      ; jank bug.
      size (cpp/.size s)]
  (println "The size is" size))

You can work around this issue by defining a helper function which does the C++ work for you. In this case, we could do the following.

(cpp/raw "size_t get_string_size(std::string const &s)
          { return s.size(); }")

(let [s (cpp/std.string)
      size (cpp/get_string_size s)]
  (println "The size is" size))

Of course, if you need to use this, please also report a bug on jank’s Github which describes what you tried to do and why it didn’t work.