All Projects → n0bra1n3r → cinterop

n0bra1n3r / cinterop

Licence: other
A C/C++ interop library for the Nim programming language

Programming Languages

nim
578 projects
C++
36643 projects - #6 most used programming language

Projects that are alternatives of or similar to cinterop

nim-presentation-slides
Nim Presentation Slides and Examples.
Stars: ✭ 30 (-48.28%)
Mutual labels:  nim-lang
geoguessrnim
GeoGuessr browser plugin, hide Ads, Filters for StreetView and Mapillary for Chromium and Firefox
Stars: ✭ 17 (-70.69%)
Mutual labels:  nim-lang
KodiSharp
Use Kodi python APIs in C#, and write rich addons using the .NET framework/Mono
Stars: ✭ 22 (-62.07%)
Mutual labels:  interop
nimfmt
Nim code formatter / linter / style checker
Stars: ✭ 75 (+29.31%)
Mutual labels:  nim-lang
DotNET.jl
Julia ❤️ .NET
Stars: ✭ 75 (+29.31%)
Mutual labels:  interop
genoiser
use the noise
Stars: ✭ 15 (-74.14%)
Mutual labels:  nim-lang
nim-mathexpr
Tiny math expression evaluator library implemented in pure Nim
Stars: ✭ 58 (+0%)
Mutual labels:  nim-lang
clojure-tensorflow
An extremely light layer over TensorFlow's Java api
Stars: ✭ 110 (+89.66%)
Mutual labels:  interop
UnityNativeTool
Allows to unload native plugins in Unity3d editor
Stars: ✭ 147 (+153.45%)
Mutual labels:  interop
Mail-Merge-Examples
Mail merge data to a Word document in C#, VB.NET without Microsoft Word or interop.
Stars: ✭ 26 (-55.17%)
Mutual labels:  interop
DotNetJS
Consume C# in JavaScript with comfort: single-file UMD library, auto-generated 2-way bindings and type definitions
Stars: ✭ 551 (+850%)
Mutual labels:  interop
nimSocks
A filtering SOCKS proxy server and client library written in nim.
Stars: ✭ 51 (-12.07%)
Mutual labels:  nim-lang
nim-new-backend
Template to create a new Backend for Nim, based on the JavaScript Backend, as minimalistic as possible to focus on codegen
Stars: ✭ 40 (-31.03%)
Mutual labels:  nim-lang
ll
ll - a more informative `ls`, based on `k`
Stars: ✭ 24 (-58.62%)
Mutual labels:  nim-lang
ajax
Ajax wrapper for nim js backend
Stars: ✭ 18 (-68.97%)
Mutual labels:  nim-lang
speckle-blender
speckle.systems/tag/blender/
Stars: ✭ 38 (-34.48%)
Mutual labels:  interop
speckle-sharp
.NET SDK, Schema and Connectors: Revit, Rhino, Grasshopper, Dynamo, ETABS, AutoCAD, Civil3D & more.
Stars: ✭ 214 (+268.97%)
Mutual labels:  interop
clojure.joda-time
An idiomatic Clojure wrapper for Joda-Time
Stars: ✭ 28 (-51.72%)
Mutual labels:  interop
nim-mod
A Nim MOD player just for fun
Stars: ✭ 40 (-31.03%)
Mutual labels:  nim-lang
haxe-c-bridge
Easily interact with haxe classes from C with an automatically generated C header
Stars: ✭ 46 (-20.69%)
Mutual labels:  interop

cinterop

Testing

A C/C++ interop library for the Nim programming language.

This project was directly inspired by the nimline library.

Overview

Similar to nimline, this library allows one to interop with C/C++ code without having to create wrappers. Unlike nimline, cinterop does not depend on Nim's experimental dotOperators feature and relies only on Nim's macro system to generate code.

Features include:

  • No dependencies other than Nim's standard library.
  • Convenience macros to declare C/C++ types and functions (decls.nim).
  • Conversion of a subset of Nim to its syntactical equivalent in C/C++ without requiring forward declarations (exprs.nim).

This project is not a replacement for hand-written wrappers or wrapper generators like c2nim. This library is useful for quickly prototyping new code that depends on large C/C++ libraries, and is carefully designed so code can progressively be migrated to use Nim's header and importcpp pragmas directly.

Recommended compiler switches

This project uses Nim's ARC and C++17. It is well tested with non-trivial code using the Visual Studio compiler on Windows. The recommended compiler switches are indicated at the top of the main test file.

Showcase

Please see tests for examples of most features. This section provides an incomplete summary of the core functionality.

C++ Class interop

Say you have the following C++ class:

// simple.hpp

class CppClass1
{
public:
    int field1 = 1;

    int method1(int arg)
    {
        return 1 + arg;
    }
};

You simply need to declare the C++ type and the source file it resides in:

# simple.nim

import cinterop/decls

csource "simple.hpp":
  type CppClass1* = object of CClass

and then you can access the fields and methods of that type:

# main.nim

import cinterop/exprs

var instance1 = CppClass1.init()

echo cexpr[cint]^instance1.field1 # prints "1"

cexpr[cint]^instance1.field1 = 2

echo cexpr[cint]^instance1.method1(instance1.field1) # prints "3"

Notice that cexpr[T]^ indicates the return type T of the whole expression, and only needs to be used at the beginning. This means that types for members do not need to be declared, as long as the type of the variable whose members are accessed is known.

Void returns

For expressions that evaluate to void, one can use the cexpr^ invocation, which is shorthand for cexpr[void]^:

cexpr^instance1.method1(0)

Type inference

If the type of a return value does not need to be known but is used in an operation, one can use the cauto^ invocation like so:

cauto^instance1.field1 += 2

Binary operations

A cexpr[T]^ invocation can appear on either side of a binary operation. cauto^ can only be used on the right-hand side unless the left-hand side is also a cauto^ invocation. Examples:

cexpr[cint]^instance1.field1 += cexpr[cint]^instance1.field1

cauto^instance1.field1 += cexpr[cint]^instance1.field1 # same as above

cauto^instance1.field1 += cauto^instance1.field1 # same as above

Free function interop

The following technique can be used for libraries with lots of functions that don't hang off of classes:

# glfw3.nim

csource &"{GLFW}/glfw3.h": # header file
  type cglfw* {.cgen:"(glfw$1(@))".} = object of CClass
# canvas.nim
...
cauto^cglfw.GetMouseButton(self.window, button) == 1
# generates something like `glfwGetMouseButton(self.window, button) == 1`
...

cglfw here serves as a namespace that is not visible in C++. The cgen pragma tells the compiler how cglfw.GetMouseButton(self.window, button) should be generated and has the same semantics as Nim's importcpp pragma.

Enums

For working with C/C++ enums, one can use the cenum pragma like so:

type CPP_ENUM* {.cenum.} = object

Although enums can be emulated using CClass and static methods, cenum provides better checking of enum semantics and produces better C/C++ code for enums. By default, enum field access results in an expansion similar to the following:

let enumValue = cauto^CPP_ENUM.MEMBER_1
# generates `CPP_ENUM enumValue = CPP_ENUM_MEMBER_1`

Custom code generation for enums can be achieved using cgen as well.

Gotchas

Unary operations

Unary operators cannot be used with cexpr[T]^ and cauto^ invocations without using parentheses:

# echo -cauto^instance1.field1 # error

echo -(cauto^instance1.field1) # compiles

There is a proposal to avoid this issue and enable a more natural implementation of cexpr[T]^.

Initialization

cauto^ can be used on the right-hand side of an initialization, but doing so may cause backend compile errors, especially if done at the global scope:

let value = cauto^instance1.field1 # C++ backend may produce an error here

If this issue is encountered, the workaround is to explicitly specify the type:

let value = cexpr[cint]^instance1.field1

Other issues are documented in the tests.

Installing

Thanks to @mantielero for adding initial support for nimble! The package can be installed by following the nimble instructions here.

Usage

Typical usage is to import cinterop/decls in modules that declare C/C++ types, and to import those modules along with cinterop/exprs to make use of them in other modules.

Contributing

This project is maintained during my free time, and serves as a tool for a game engine I am writing after work hours. Contributions are welcome, and I will merge them immediately if they serve to keep the project robust, simple, and maintainable.

Cheers and happy coding! 🍺

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].