dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.09k stars 4.7k forks source link

Mono terminates Program when calling Console.WriteLine from C++ #80803

Closed MizuFelix closed 1 year ago

MizuFelix commented 1 year ago

Description

Hello! I'm currently working on a Game Engine in C++ with C# as scripting language. I wanted to call a function from C#, that calls Console.WriteLine(). But I got an error and couldn't fix it. I'm on MacOS Ventura and use Mono 12.0.

Reproduction Steps

Error from Terminal:

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'System.Console' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.ConsoleDriver' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Sys' threw an exception. ---> System.DllNotFoundException: System.Native assembly:<unknown assembly> type:<unknown type> member:(null)

There is a little more text but I don't know if it makes sense posting it...

C++ Code:

mono_set_dirs("/Library/Frameworks/Mono.framework/Versions/6.12.0/lib", "/Library/Frameworks/Mono.framework/Versions/6.12.0/etc");

        m_MonoDomain = mono_jit_init("MCCScriptEngine");
        if (m_MonoDomain)
        {
            MCC_DEV_CONSOLE("Opened MonoDomain! (C#)");

            m_MainAssembly = mono_domain_assembly_open(m_MonoDomain, "MCC-ScriptCore.dll");
            if (m_MainAssembly)
            {
                MCC_DEV_CONSOLE("Opened MainAssembly (C#)");

                m_MainImage = mono_assembly_get_image(m_MainAssembly);
                if (m_MainImage)
                {
                    MCC_DEV_CONSOLE("Opened MainImage (C#)");

                    MonoClass *MainClass = mono_class_from_name(m_MainImage, "MCC", "Main");
                    if (MainClass)
                    {
                        MCC_DEV_CONSOLE("Opened MainClass! (C#)");

                        MonoMethodDesc *InfoTextDesc = mono_method_desc_new(".Main:InfoText()", false);
                        if (InfoTextDesc)
                        {
                            MCC_DEV_CONSOLE("found InfoText() (C#)");

                            MonoMethod *InfoText = mono_method_desc_search_in_class(InfoTextDesc, MainClass);
                            if (InfoText)
                            {
                                MCC_DEV_CONSOLE("Initialized Method");

                                mono_runtime_invoke(InfoText, nullptr, nullptr, nullptr);
                            }
                        }
                    }
                }
            }
        }

MCC_DEV_CONSOLE() is just a macro that calls std::out

C# Code:

using System;

namespace MCC
{
    public class Main
    {
        public Main()
        {
            Console.WriteLine("Main ScriptConstructor!");
        }

        public static void InfoText()
        {
            Console.WriteLine("The MCC-Engine is a Game Engine written in C++ and C#!");
        }

        public void Print(string message)
        {
            Console.WriteLine(message);
        }
    }
}

Expected behavior

It should print: "The MCC-Engine is a Game Engine written in C++ and C#!" to the Console

Actual behavior

Throws an error

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

dotnet-issue-labeler[bot] commented 1 year ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

MizuFelix commented 1 year ago

In case anyone is seeing this in the future, you have to call mono_config_parse("/Library/Frameworks/Mono.framework/Versions/6.12.0/etc/mono/config"); before you call mono_jit_init();