[Mono-dev] Mono in Ubuntu thread

howard.rubin howard.rubin at hl.konicaminolta.us
Tue Apr 11 21:30:38 UTC 2017


My program (below) works on Fedora 22 or if I call the thread function
directly from main(). But if I launch the mono calls in a thread on Ubuntu
16.04, it asserts like this. Am I doing something wrong?
Howard Rubin

Output:

$ rm monotest.dll ; make ; ./monotest
Mono C# compiler version 4.8.0.0
mcs monotest.cs /out:monotest.dll /target:library
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
g++ monotest.cpp -o monotest -g3 -std=c++11 `pkg-config --cflags --libs
mono-2`
MySum(1,2) => 3
* Assertion at mono-threads-posix.c:265, condition `info->handle' not met

Aborted (core dumped)
$ 

///////////////////////////////
// monotest.cpp
#include <thread>
#include <sstream>
#include <iostream>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

MonoDomain* domain;
MonoImage* image;

MonoObject* Create(void* args[],
                   const char* namespacename, const char* classname, const
char* paramnames);
MonoObject* Call(MonoObject* theObject, void* args[],
                 const char* namespacename, const char* classname, const
char* functionsignature);

void Thread() {
    domain = mono_jit_init("monotest.dll");
    MonoAssembly* assembly = mono_domain_assembly_open(domain,
"monotest.dll");
    image = mono_assembly_get_image(assembly);

    int one = 1, two = 2;
    void* args[] = { &one, &two };

    MonoObject* MyClass = Create(nullptr, "MyNamespace", "MyClass", "");

    Call(MyClass, args, "MyNamespace", "MyClass", "MySum (int,int)");

    mono_jit_cleanup(domain);
}

int main() {
    //Thread();
    std::thread t(Thread);
    t.join();

}

MonoObject* Call(MonoObject* theObject, void* args[],
                 const char* namespacename, const char* classname, const
char* functionsignature) {

    MonoClass* theClass = mono_class_from_name(image, namespacename,
classname);
    if (theClass == nullptr) {
        std::cout << "mono_class_from_name(\"" << namespacename << "\",\""
<< classname
                  << "\") returned null for \"" << functionsignature << '"'
<< std::endl;
        return nullptr;
    }

    std::ostringstream os; // e.g.
"DocumentFormat.OpenXml.Packaging.WordprocessingDocument:AddMainDocumentPart()"
    os << namespacename << '.' << classname << ':' << functionsignature;
    std::string str = os.str();
    MonoMethodDesc* theDesc = mono_method_desc_new(str.c_str(), true);
    if (theDesc == nullptr) {
        std::cout << "mono_method_desc_new(" << str << ") returned null for
\""
                  << functionsignature << '"' << std::endl;
        return nullptr;
    }

    MonoMethod* theMethod = mono_method_desc_search_in_class(theDesc,
theClass);
    if (theMethod == nullptr) {
        std::cout << "mono_method_desc_search_in_class() returned null for
\""
                  << functionsignature << '"' << std::endl;
        return nullptr;
    }

    MonoObject* exception = NULL;
    MonoObject* returnValue = mono_runtime_invoke(theMethod, theObject,
args, &exception);
    if (exception)
        mono_print_unhandled_exception(exception);

    return returnValue;
}

static bool ErrorMessage(const void* value, const char* function, int line,
const char* sourcefile) {
    if (value == nullptr)
        std::cout << function << "() returned null (line " << line << " of
file " << sourcefile << std::endl;
    return value == nullptr;
}
MonoObject* Create(void* args[],
                   const char* namespacename, const char* classname, const
char* paramnames) {

    MonoClass* theClass = mono_class_from_name(image, namespacename,
classname);
    if (ErrorMessage(theClass, "mono_class_from_name", __LINE__, __FILE__))
        return nullptr;

    std::ostringstream os; // e.g.
"DocumentFormat.OpenXml.Wordprocessing.Text:.ctor(string)"
    os << namespacename << '.' << classname << ":.ctor (" << paramnames <<
')';
    std::string str = os.str();
    MonoMethodDesc* theDesc = mono_method_desc_new(str.c_str(), false);
    if (ErrorMessage(theDesc, "mono_method_desc_new", __LINE__, __FILE__))
        return nullptr;

    MonoMethod* theCtor = mono_method_desc_search_in_class(theDesc,
theClass);
    if (ErrorMessage(theCtor, "mono_method_desc_search_in_class", __LINE__,
__FILE__))
        return nullptr;

    MonoObject* theObject = mono_object_new(domain, theClass);
    if (ErrorMessage(theObject, "mono_object_new", __LINE__, __FILE__))
        return nullptr;

    MonoObject* exception = NULL;
    mono_runtime_invoke(theCtor, theObject, args, &exception); // returns
NULL
    if (exception)
        mono_print_unhandled_exception(exception);

    return theObject;
}

////////////////////////
// monotest.cs
namespace MyNamespace  {

    public class MyClass {
        public MyClass() { }

        public void MySum(int arg1, int arg2) {
            System.Console.WriteLine("MySum(" + arg1 + "," + arg2 + ") => "
+ (arg1 + arg2));
        }
    }
}

###################
# Makefile
monotest : monotest.cpp monotest.dll Makefile
	@g++ --version | head -1
	g++ $< -o $@ -g3 -std=c++11 `pkg-config --cflags --libs mono-2`

monotest.dll : monotest.cs
	@mcs --version
	mcs $< /out:$@ /target:library






--
View this message in context: http://mono.1490590.n4.nabble.com/Mono-in-Ubuntu-thread-tp4670463.html
Sent from the Mono - Dev mailing list archive at Nabble.com.


More information about the Mono-devel-list mailing list