[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