c++ via c#
TRANSCRIPT
C++ via C#Egor Bogatov@EgorBo
Calling C++ from C#. For what?
• Lovely IDE + R#• Syntactic sugar• nuget
Calling C++ from C#. How?
• C++/CLI• COM• [DllImport],
[MethodImpl]• IPC, Sockets,…
Calling C++ from C#. How?
• C++/CLI• COM• [DllImport],
[MethodImpl]• IPC, Sockets,…
UrhoSharp• ~ 200 classes• ~ 5000 methods• Same FPS• +10% memory• C# for: Windows Mac OS Android iOS tvOS
Urho3D APIclass Node : public Animatable{public: Node(Context* context);
void SetName(const String& name); const String& GetName();
void SetPosition(const Vector3& position); const Vector3& GetPosition();
void AddChild(Node* node, unsigned index = M_MAX_UNSIGNED); void RemoveChild(Node* node);};
public class Node : Animatable{ public Node(Context context) { }
public string Name { get; set; } public Vector3 Position { get; set; }
void AddChild(Node node, uint index = uint.MaxValue) { } void RemoveChild(Node node) { }}
Node.cpp
C++
C#
Urho3D API
class Node : public Animatable{public:
Node(Context* context);
void SetName(const String& name);};
glue.cpp
Urho3D API
Node.cpp
C#Node node = new Node(context);node.SetName("foo");
Node* node = new Node(context_);node->SetName("foo");
Urho3D APIvoid SetName(const String& name);
extern "C"DllExport void Node_SetName (Node *target, const char * name){ target->SetName (Urho3D::String(name));}
[DllImport ("mono-urho", …)]static extern void Node_SetName (IntPtr handle, string name);
public void SetName (string name) { Node_SetName (handle, name);
Node.cppNode.h
binding.cpp
Node.cs
original API
generated
generated
Urho3D APIclass Node : public Animatable{public:
Node(Context* context); void SetName(const String& name);};
DllExport void* Node_Node (Context * context) { return new Node(context);}
DllExport void Node_SetName (Node *target, const char * name) { target->SetName (Urho3D::String(name));}
public partial class Node : Animatable{
private IntPtr handle;
[DllImport ("mono-urho")]static extern IntPtr Node_Node (IntPtr context);public Node (Context context) { handle = Node_Node (context.Handle); }
[DllImport ("mono-urho")]static extern void Node_SetName (IntPtr handle, string name);public void SetName (string name) { Node_SetName (handle, name);
Node.cppNode.h
binding.cpp
Node.cs
original API
generated
generated
Binding flow
Urho3D sources (*.cpp, *.h)
Urho.pch
Generator (Binder)
binding.cpp *.cs
UrhoSharp.dllWin: mono-urho.dllDroid: libmono-urho.soOSX: libmono-urho.dylibiOS: urho.framework
nuget package
all-urho.cpp via clang
roslyn
• clang• gcc• msvc
clang.dllNrefactory.dll
PCL, Profile7
Object lifecycleRefCounted:• AddRef • ReleaseRef• RefsCount• ~dctor
Node node = new Node(context)
1) Allocate a native object (Node* node = new Node)
scene.AddNode(node)
2) AddRef is called, callback to managed code3) Managed code receives the callback, adds hard reference to node
scene.RemoveAll();
5) Managed code receives callback from native ~dctor, removes reference. GC is now able to collect empty wrapper.
6) GC collects managed wrapper
Egor Bogatov@EgorBo
github:• UrhoSharp• CppSharp