Code Monkey home page Code Monkey logo

clrbridge's Introduction

clrbridge

Call .NET code from other languages. Currently focused on the D programming language, with the possibility of adding support for other langauges.

Current State

See tests to see what currently works.

Currently ClrBridge supports calling methods with primitive types and enum types. The development strategy is to translate mscorlib, but translating the whole thing requires full support, so the code generator skips unsupported constructs during this initial stage of development. As more functionality gets added, the features that are currently skipped will be enabled and unit tests added along the way.

How it Works

.NET code requires the CLR runtime to execute. This repo currently supports 2 mechanisms to initialize the CLR runtime in order to run .NET code from native code.

Method 1: Coreclr Library Host

This method uses the coreclr library to host .NET CLR assemblies from native executables. The coreclr library initializes a .NET CLR runtime within a native process, and provides functions to call static .NET methods. The ClrBridge.dll .NET library provides a set of static methods to enable full access to the .NET CLR runtime.

Here's an example program that uses this method:

import std.path;
import std.stdio;

import cstring;
import clrbridge;
import clrbridge.coreclr;

import mscorlib.system;

int main(string[] args)
{
    initGlobalClrBridgeWithCoreclr(buildPath(__FILE_FULL_PATH__.dirName, "out", "ClrBridge.dll"));

    Console.WriteLine();
    Console.WriteLine(true);
    Console.WriteLine(CStringLiteral!"hello!");

    return 0;
}

Method 2: Clr Callback Host

This method starts by running a .NET process and then P/Invoking into a native shared library and providing a callback method to grant access to the methods in ClrBridge.dll. Once the native executable has been called, this method functions the same way as the Coreclr Library Host method, where it uses ClrBridge.dll to enable full access to the .NET CLR runtime. The ClrCallbackHost.exe .NET executable can be used to run native shared libraries:

ClrCallbackHost.exe <shared_library> <args>...

This will call the _clrCallbackHostEntry entry point with the given command-line arguments and a function pointer to load methods from ClrBridge.dll. Here's an example program that uses this method:

import std.stdio;
import cstring;
import clrbridge;
import clrbridge.callbackhost;
import mscorlib.system;

export extern (C) int _clrCallbackHostEntry(CreateDelegate createDelegate, int argc, CString* argv/*, CString* envp*/)
{
    import core.runtime;
    try
    {
        Runtime.initialize();
        initGlobalClrBridgeWithCallbackHost(createDelegate);
        const result = mainClr(argc, argv);
        Runtime.terminate();
        return result;
    }
    catch (Throwable e)
    {
        printf("%s", e.toString().toCString());
        return 1;
    }
}
int mainClr(int argc, CString* argv)
{
    writefln("mainClr argc=%s!\n", argc);stdout.flush();
    for (int i = 0; i < argc; i++)
    {
        writefln("arg[%s] '%s'", i, argv[i]);
    }
    Console.WriteLine(CStringLiteral!"Calling C# from D!");
    return 0;
}

Method 3: COM Clr Host

Support for this method has not been added yet. This one is lower priority since as far as I know it will only work for Windows.

How to Build

Note that all files created should go into the "out" directory or the "out-pure" directory. "out-pure" will contain files that doesn't need to be cleaned/regenerated (i.e. versioned source trees from other projects).

You can run a full clean build with:

rund minish.d cleanBuildAll

The build is separated into individual steps which you can see in cleanBuildAll.

Notes

Currently I use a sequence of calls to create/pass arrays to the CLR. Instead, I could leverage the technique I use for return values to create an array in one call. Namely, layout the array elements in memory, then call a function to serialize it into a .NET array. ClrBridge would iterate over each elements, marshaling each value like it does a return value. Note that this is just an optimization, I'll have to check performance to see if this extra code is worth it.

Idea: Using D's GC to release C# object references

All .NET Object references returned by ClrBridge are "pinned", meaning that C# will not garbage collect them. It is up to the D code to release object references in order for the Clr to collect them. Right now the D application can call globalClrBridge.release to release a reference, however, I'd like to see if it's feasible to have the D garbage collector call this automatically when these C# objects are out of scope and no longer referenced. I believe this will require wrapping the .NET object references to D objects allocated on the heap.

TODO

ClrBridge Assembly Resolution

Add support in ClrBridge to resolve assemblies when they are missing. This is the same thing that ClrBridgeCodegen does with

        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolveCallback);

Might provide a function in ClrBridge.dll that allows the client to add assembly paths.

Dll FileName Info in Generated Code

I should include some information about the original DLL in the generated Code. Information that could help ClrBridge find the dll at runtime.

clrbridge's People

Contributors

marler8997 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

laeeth chigusa0w0

clrbridge's Issues

[Bug] Error 1: Previous Definition Different

When trying to execute the step rund example.d while building the project with command rund minish.d cleanBuildAll, tons of error spawned saying Error 1: Previous Definition Different {Mangled Name Here}.

After reading the codegen source code. I found that currently clrbridge lacks of a way to handle different overloads with only non-primitive parameters have different type.

For example, for Marshal.ReadInt64, both of its two-parameter overloads become ReadInt64(__d.clr.DotNetObject, int). Thus a case of the above mentioned Error 1 occurred.

Could there be a way to identify and fix this issue?

A possible way to solve this is to generate DotNetObject_IntPtr for C# IntPtr, DotNetObject_Object for C# Object and alias this each of these DotNetObject_??? to DotNetObject so that the line __d.globalClrBridge.box!"Object" could leave unchanged.

e.g.:
ReadInt64(IntPtr, Int32) -> ReadInt64(__d.clr.DotNetObject_IntPtr, int)
ReadInt64(Object, Int32) -> ReadInt64(__d.clr.DotNetObject_Object, int)

Also worth mentioning, as you may know, not everything in C# derives from object. So, although I haven't tested this by myself, try calling some String Constructors (and other methods with pointer-type or TypedReference parameters) may cause error or unexpected behaviour, thus need to be excluded from codegen procedure.

PS. may I ask what license is applied to this project?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.