mono / Embeddinator-4000

Tools to turn .NET libraries into native libraries that can be consumed on Android, iOS, Mac, Linux and other platforms.
MIT License
758 stars 95 forks source link

Does Embeddinator-4000's generated C code support .NET APIs that return .NET interfaces or objects? #682

Closed jbielski closed 6 years ago

jbielski commented 6 years ago

Apologize in advance if I simply misunderstand the function that Embeddinator is supposed to provide. I'm new to .NET.

Steps to Reproduce

  1. Create a .NET wrapper class library with a narrow interface that calls other .NET class library's business logic
  2. Use Embeddinator-4000.exe to generate C code for the wrapper class
  3. Embeddinator-4000 generates C code and a *.dylib for wrapper class

Expected Behavior

C code generated for all the APIs in my .NET wrapper class library

Actual Behavior

C code only generated for .NET APIs that return strings and ints, not for those that return .NET class objects or interfaces

Environment

This is my wrapper class. I only got setters and getters for variables with native types. using System; using System.IO; using System.IO.Compression; using AgGateway.ADAPT.ApplicationDataModel.ADM; using AgGateway.ADAPT.PluginManager;

namespace ADMWrapper { public class Wrapper { // Find and initialize the ADM Plugin private static IPlugin AdmPlugin { get; set; } private static string SourcePath { get; set; } private static ApplicationDataModel DataModel { get; set; } //private static GrowerTree GrowerTree { get; set; } private static int UseGrowerId { get; set; } = 0; private static int UseFarmId { get; set; } = 0; private static int UseFieldId { get; set; } = 0;

    private static IPlugin InitializeAdaptPlugin()
    {
        IPlugin iPlugin = null;
        try
        {
            var appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            var pluginFactory = new PluginFactory(appPath);
            iPlugin = pluginFactory.GetPlugin("ADMPlugin");
            iPlugin.Initialize();
        }
        catch (Exception exp)
        {
            throw exp;
        }
        return iPlugin;
    }

    // Import the ADM Model
    private static void UnzipSampleData()
    {
        SourcePath = "/Users/Shared/Projects/ADAPT/ADM";
        var dirInfo = new DirectoryInfo(SourcePath);
        foreach (FileInfo file in dirInfo.GetFiles())
            file.Delete();
        foreach (DirectoryInfo dir in dirInfo.GetDirectories())
            dir.Delete(true);

        var appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
        var source = Path.Combine(appPath, @"Resources/TreeDemoADM.zip");
        ZipFile.ExtractToDirectory(source, SourcePath);
    }

    // Get the model's catalog
    private static ApplicationDataModel LoadAdaptDataModel()
    {
        var models = AdmPlugin.Import(SourcePath);
        if (models.Count > 0)
        {
            DataModel = models[0];
            //GrowerTree = new GrowerTree( DataModel );
            //GrowerTree.BuildFromCropZones();
        }
        else
            throw new Exception($"There were no ADAPT Application Data Models found at {SourcePath}.");

        return DataModel;
    }
    // Get a particular Grower, Farm, and Field from the model
}

}

Build Logs

Example Project (If Possible)

mandel-macaque commented 6 years ago

Hello, I'm not an expert on that side, but I have added the c tag to get the attention of the right developers. Thanks for the bug report/question.

jbielski commented 6 years ago

Thank you. Since I opened this bug report, I figured out that I was hitting the documented limitation: you cannot use two different .NET Embedding-generated libraries inside the same application. So I applied the workaround of passing multiple DLLs on the command line. Now I hit a different problem, but still having to do with the C bindings. Should I open another bug report or add on to this one?

jbielski commented 6 years ago

public partial class RepresentationSystemRepresentationsEnumeratedRepresentation { public object[] Items; ...

Gets translated to this:

and this: void AgGateway_ADAPT_Representation_Generated_RepresentationSystemRepresentationsEnumeratedRepresentation_set_Items(AgGateway_ADAPT_Representation_Generated_RepresentationSystemRepresentationsEnumeratedRepresentation object, value) { static MonoClassField field = 0; if (!field) { lookup_class_AgGateway_ADAPT_Representation_Generated_RepresentationSystemRepresentationsEnumeratedRepresentation(); const char field_name[] = "Items"; field = mono_class_get_field_from_name(class_AgGateway_ADAPT_Representation_Generated_RepresentationSystemRepresentationsEnumeratedRepresentation, field_name); } void value = ; MonoObject* instance = mono_gchandle_get_target(object->_handle); mono_field_set_value(instance, field, __value); } which results in this compilation error: ADAPTShared_c/AgGateway.ADAPT.Representation.c:2389:21: error: expected expression void* __value = ;

mandel-macaque commented 6 years ago

@jbielski please file a new issue so that we can have a clean start and focus on the right problem. Once you have created the issue, please close this bug and link to it so that if other users have the smaller problem can follow up.

jbielski commented 6 years ago

Opened issue 686 instead