Mono in Ubuntu thread

"howard.rubin" <[email protected]>
Newsgroups gmane.comp.gnome.mono.devel
Message-ID <[email protected]>
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.
_______________________________________________
Mono-devel-list mailing list
[email protected]
http://lists.dot.net/mailman/listinfo/mono-devel-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.