#if defined(WIN32) && defined (_MSC_VER)
#define LIBTEST_API __declspec(dllexport)
#elif defined(__GNUC__)
-#define LIBTEST_API __attribute__ ((visibility ("default")))
+#define LIBTEST_API __attribute__ ((__visibility__ ("default")))
#else
#define LIBTEST_API
#endif
int slen = strlen (str);
gunichar2* temp;
/* allocate len + 1 utf16 characters plus 4 byte integer for length*/
- ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
+ ret = (gchar *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
if (ret == NULL)
return NULL;
temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
int i = 0;
unsigned short *res;
- res = marshal_alloc (2 * (length + 1));
+ res = (unsigned short *)marshal_alloc (2 * (length + 1));
// printf("test_lpwstr_marshal()\n");
const char abc[] = "ABC";
glong len = strlen(abc);
- *chars = marshal_alloc (2 * (len + 1));
+ *chars = (unsigned short *)marshal_alloc (2 * (len + 1));
while ( i < len ) {
(*chars) [i] = abc[i];
int i, len;
len = 4;
- arr = marshal_alloc (sizeof (gint32) * len);
+ arr = (gint32 *)marshal_alloc (sizeof (gint32) * len);
for (i = 0; i < len; ++i)
arr [i] = i;
*out_arr = arr;
mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
{
/* Check that the input pointer is ignored */
- ss->d = (gpointer)0x12345678;
+ ss->d = (const char *)0x12345678;
func (a, ss, b);
return delegate;
}
-typedef int DelegateByrefDelegate (void *);
+typedef int (STDCALL *DelegateByrefDelegate) (void *);
LIBTEST_API int STDCALL
mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del)
{
- int (*ptr) (int i);
+ int (STDCALL *ptr) (int i);
del (&ptr);
simplestruct *ptr;
/* Check that the input pointer is ignored */
- ptr = (gpointer)0x12345678;
+ ptr = (simplestruct *)0x12345678;
res = delegate (&ptr);
if (res != 0)
LIBTEST_API int STDCALL
mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
{
- return delegate (ftn);
+ return delegate ((return_int_fnt)ftn);
}
static int STDCALL
return (d ()) (55);
}
+typedef int (STDCALL *VirtualDelegate) (int);
+
+LIBTEST_API int STDCALL
+mono_test_marshal_virtual_delegate (VirtualDelegate del)
+{
+ return del (42);
+}
+
+typedef char* (STDCALL *IcallDelegate) (const char *);
+LIBTEST_API int STDCALL
+mono_test_marshal_icall_delegate (IcallDelegate del)
+{
+ char *res = del ("ABC");
+ return strcmp (res, "ABC") == 0 ? 0 : 1;
+}
+
LIBTEST_API int STDCALL
mono_test_marshal_stringbuilder (char *s, int n)
{
if (strcmp (s, "ABCD") != 0)
return 1;
- strncpy(s, m, n);
+ memcpy(s, m, n);
s [n] = '\0';
return 0;
}
{
const char m[] = "This is my message. Isn't it nice?";
- strncpy(s, m, n);
+ memcpy(s, m, n);
s [n] = '\0';
return 0;
}
const char m[] = "This is my message. Isn't it nice?";
char *str;
- str = marshal_alloc (strlen (m) + 1);
+ str = (char *)marshal_alloc (strlen (m) + 1);
memcpy (str, m, strlen (m) + 1);
*s = str;
s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
len = (len * 2) + 2;
- *s = marshal_alloc (len);
+ *s = (gunichar2 *)marshal_alloc (len);
memcpy (*s, s2, len);
g_free (s2);
if (strcmp (*s, "ABC"))
return 1;
- str = marshal_alloc (strlen (m) + 1);
+ str = (char *)marshal_alloc (strlen (m) + 1);
memcpy (str, m, strlen (m) + 1);
*s = str;
return 0;
}
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++-compat"
+#endif
+
+/*
+* Standard C and C++ doesn't allow empty structs, empty structs will always have a size of 1 byte.
+* GCC have an extension to allow empty structs, https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html.
+* This cause a little dilemma since runtime build using none GCC compiler will not be compatible with
+* GCC build C libraries and the other way around. On platforms where empty structs has size of 1 byte
+* it must be represented in call and cannot be dropped. On Windows x64 structs will always be represented in the call
+* meaning that an empty struct must have a representation in the callee in order to correctly follow the ABI used by the
+* C/C++ standard and the runtime.
+*/
typedef struct {
-#ifndef __GNUC__
+#if !defined(__GNUC__) || defined(TARGET_WIN32)
char a;
#endif
} EmptyStruct;
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
LIBTEST_API int STDCALL
mono_test_marshal_empty_string_array (char **array)
{
{
EmptyStruct s;
+ memset (&s, 0, sizeof (s));
+
+#if !(defined(__i386__) && defined(__clang__))
+ /* https://bugzilla.xamarin.com/show_bug.cgi?id=58901 */
g_assert (a == 42);
+#endif
return s;
}
{
ByValStrStruct *ret;
- ret = malloc(sizeof(ByValStrStruct));
+ ret = (ByValStrStruct *)malloc (sizeof (ByValStrStruct));
memset(ret, 'a', sizeof(ByValStrStruct)-1);
ret->a[sizeof(ByValStrStruct)-1] = 0;
LIBTEST_API void STDCALL
class_marshal_test1 (SimpleObj **obj1)
{
- SimpleObj *res = malloc (sizeof (SimpleObj));
+ SimpleObj *res = (SimpleObj *)malloc (sizeof (SimpleObj));
res->str = marshal_strdup ("ABC");
res->i = 5;
GError *error = NULL;
char *s;
- s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
+ s = g_utf16_to_utf8 ((const gunichar2 *)ptr, -1, NULL, NULL, &error);
if (!s)
return 1;
LIBTEST_API int STDCALL
mono_test_marshal_asany_in (void* ptr)
{
- AsAnyStruct* asAny = ptr;
+ AsAnyStruct *asAny = (AsAnyStruct *)ptr;
int res = asAny->i + asAny->j + asAny->k;
return res;
LIBTEST_API int STDCALL
mono_test_marshal_asany_inout (void* ptr)
{
- AsAnyStruct* asAny = ptr;
+ AsAnyStruct *asAny = (AsAnyStruct *)ptr;
int res = asAny->i + asAny->j + asAny->k;
marshal_free (asAny->s);
LIBTEST_API int STDCALL
mono_test_marshal_asany_out (void* ptr)
{
- AsAnyStruct* asAny = ptr;
+ AsAnyStruct *asAny = (AsAnyStruct *)ptr;
int res = asAny->i + asAny->j + asAny->k;
asAny->i = 10;
buf [0] = 0;
buf [1] = 10;
- ptr = del (&buf);
+ ptr = (guint32 *)del (&buf);
res = ptr [1];
int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
+ int (STDCALL *Return22NoICall)(MonoComObject* pUnk);
} MonoIUnknown;
struct MonoComObject
return S_OK;
}
+LIBTEST_API int STDCALL
+Return22NoICall(MonoComObject* pUnk)
+{
+ return 22;
+}
+
+
static void create_com_object (MonoComObject** pOut);
LIBTEST_API int STDCALL
(*pOut)->vtbl->ITestIn = ITestIn;
(*pOut)->vtbl->ITestOut = ITestOut;
(*pOut)->vtbl->get_ITest = get_ITest;
+ (*pOut)->vtbl->Return22NoICall = Return22NoICall;
}
static MonoComObject* same_object = NULL;
return 0;
}
+// Xamarin-47560
+LIBTEST_API int STDCALL
+mono_test_marshal_array_ccw_itest (int count, MonoComObject ** ppUnk)
+{
+ int hr = 0;
+
+ if (!ppUnk)
+ return 1;
+
+ if (count < 1)
+ return 2;
+
+ if (!ppUnk[0])
+ return 3;
+
+ hr = ppUnk[0]->vtbl->SByteIn (ppUnk[0], -100);
+ if (hr != 0)
+ return 4;
+
+ return 0;
+}
+
/*
* mono_method_get_unmanaged_thunk tests
*/
#if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
-#define ALIGN(size) __attribute__ ((aligned(size)))
+#define ALIGN(size) __attribute__ ((__aligned__(size)))
#else
#define ALIGN(size)
#endif
int ret = 0;
gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
- = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
+ = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
gpointer (*mono_string_new_wrapper)(const char *)
- = lookup_mono_symbol ("mono_string_new_wrapper");
+ = (gpointer (*)(const char *))lookup_mono_symbol ("mono_string_new_wrapper");
- char* (*mono_string_to_utf8)(gpointer)
- = lookup_mono_symbol ("mono_string_to_utf8");
+ char *(*mono_string_to_utf8)(gpointer)
+ = (char *(*)(gpointer))lookup_mono_symbol ("mono_string_to_utf8");
gpointer (*mono_object_unbox)(gpointer)
- = lookup_mono_symbol ("mono_object_unbox");
+ = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_object_unbox");
gpointer (*mono_threads_enter_gc_unsafe_region) (gpointer)
- = lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
+ = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
void (*mono_threads_exit_gc_unsafe_region) (gpointer, gpointer)
- = lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
+ = (void (*)(gpointer, gpointer))lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
goto done;
}
- CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
+ CreateObject = (gpointer (STDCALL *)(gpointer *))mono_method_get_unmanaged_thunk (create_object_method_handle);
if (!CreateObject) {
ret = 3;
goto done;
case 0: {
/* thunks.cs:Test.Test0 */
- void (STDCALL *F)(gpointer*) = test_method;
+ void (STDCALL *F)(gpointer *) = (void (STDCALL *)(gpointer *))test_method;
F (&ex);
break;
}
case 1: {
/* thunks.cs:Test.Test1 */
- int (STDCALL *F)(gpointer*) = test_method;
+ int (STDCALL *F)(gpointer *) = (int (STDCALL *)(gpointer *))test_method;
if (F (&ex) != 42) {
ret = 4;
goto done;
case 2: {
/* thunks.cs:Test.Test2 */
- gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
+ gpointer (STDCALL *F)(gpointer, gpointer*) = (gpointer (STDCALL *)(gpointer, gpointer *))test_method;
gpointer str = mono_string_new_wrapper ("foo");
if (str != F (str, &ex)) {
ret = 4;
gpointer obj;
gpointer str;
- F = test_method;
+ F = (gpointer (STDCALL *)(gpointer, gpointer, gpointer *))test_method;
obj = CreateObject (&ex);
str = mono_string_new_wrapper ("bar");
gpointer obj;
gpointer str;
- F = test_method;
+ F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
obj = CreateObject (&ex);
str = mono_string_new_wrapper ("bar");
gpointer obj;
gpointer str;
- F = test_method;
+ F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
obj = CreateObject (&ex);
str = mono_string_new_wrapper ("bar");
gpointer str = mono_string_new_wrapper ("Test6");
int res;
- F = test_method;
+ F = (int (STDCALL *)(gpointer, guint8, gint16, gint32, gint64, float, double, gpointer, gpointer *))test_method;
obj = CreateObject (&ex);
res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
case 7: {
/* thunks.cs:Test.Test7 */
- gint64 (STDCALL *F)(gpointer*) = test_method;
+ gint64 (STDCALL *F)(gpointer*) = (gint64 (STDCALL *)(gpointer *))test_method;
if (F (&ex) != G_MAXINT64) {
ret = 4;
goto done;
double a6;
gpointer a7;
- F = test_method;
+ F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
+ gpointer *, gpointer *))test_method;
F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
if (ex) {
case 9: {
/* thunks.cs:Test.Test9 */
void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
- gpointer*, gpointer*);
+ gpointer*, gpointer*);
guint8 a1;
gint16 a2;
double a6;
gpointer a7;
- F = test_method;
+ F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
+ gpointer *, gpointer *))test_method;
F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
if (!ex) {
goto done;
}
- F = test_method;
+ F = (void (STDCALL *)(gpointer *, gpointer *))test_method;
F (&obj1, &ex);
if (ex) {
goto done;
}
- a1 = mono_object_unbox (obj);
+ a1 = (TestStruct *)mono_object_unbox (obj);
if (!a1) {
ret = 6;
goto done;
a1->A = 42;
a1->B = 3.1415;
- F = test_method;
+ F = (int (STDCALL *)(gpointer *, gpointer *))test_method;
- res = F (obj, &ex);
+ res = F ((gpointer *)obj, &ex);
if (ex) {
ret = 7;
goto done;
goto done;
}
- a1 = mono_object_unbox (obj);
+ a1 = (TestStruct *)mono_object_unbox (obj);
if (!a1) {
ret = 6;
goto done;
}
- F = test_method;
+ F = (void (STDCALL *)(gpointer, gpointer *))test_method;
F (obj, &ex);
if (ex) {
TestStruct *a1;
gpointer obj;
- F = test_method;
+ F = (gpointer (STDCALL *)(gpointer *))test_method;
obj = F (&ex);
if (ex) {
goto done;
}
- a1 = mono_object_unbox (obj);
+ a1 = (TestStruct *)mono_object_unbox (obj);
if (a1->A != 42) {
ret = 5;
goto done;
}
- a1 = mono_object_unbox (obj);
+ a1 = (TestStruct *)mono_object_unbox (obj);
if (!a1) {
ret = 6;
a1->A = 42;
a1->B = 3.1415;
- F = test_method;
+ F = (void (STDCALL *)(gpointer, gpointer *))test_method;
F (obj, &ex);
if (ex) {
static void
call_managed (gpointer arg)
{
- SimpleDelegate del = arg;
+ SimpleDelegate del = (SimpleDelegate)arg;
call_managed_res = del (42);
}
int res;
pthread_t t;
- res = pthread_create (&t, NULL, (gpointer)call_managed, del);
+ res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed, del);
+ g_assert (res == 0);
+ pthread_join (t, NULL);
+
+ return call_managed_res;
+#endif
+}
+
+typedef struct {
+ char arr [4 * 1024];
+} LargeStruct;
+
+typedef int (STDCALL *LargeStructDelegate) (LargeStruct *s);
+
+static void
+call_managed_large_vt (gpointer arg)
+{
+ LargeStructDelegate del = (LargeStructDelegate)arg;
+ LargeStruct s;
+
+ call_managed_res = del (&s);
+}
+
+LIBTEST_API int STDCALL
+mono_test_marshal_thread_attach_large_vt (SimpleDelegate del)
+{
+#ifdef WIN32
+ return 43;
+#else
+ int res;
+ pthread_t t;
+
+ res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed_large_vt, del);
g_assert (res == 0);
pthread_join (t, NULL);
LIBTEST_API char* STDCALL
mono_test_marshal_return_lpstr (void)
{
- char *res = marshal_alloc (4);
+ char *res = (char *)marshal_alloc (4);
strcpy (res, "XYZ");
return res;
}
LIBTEST_API gunichar2* STDCALL
mono_test_marshal_return_lpwstr (void)
{
- gunichar2 *res = marshal_alloc (8);
+ gunichar2 *res = (gunichar2 *)marshal_alloc (8);
gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
memcpy (res, tmp, 8);
return sa4;
}
+typedef struct {
+ int array [3];
+} FixedArrayStruct;
+
+LIBTEST_API int STDCALL
+mono_test_marshal_fixed_array (FixedArrayStruct s)
+{
+ return s.array [0] + s.array [1] + s.array [2];
+}
+
+typedef struct {
+ char array [16];
+ char c;
+} FixedBufferChar;
+
+LIBTEST_API int STDCALL
+mono_test_marshal_fixed_buffer_char (FixedBufferChar *s)
+{
+ if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
+ return 1;
+ s->array [0] = 'E';
+ s->array [1] = 'F';
+ s->c = 'G';
+ return 0;
+}
+
+typedef struct {
+ short array [16];
+ short c;
+} FixedBufferUnicode;
+
+LIBTEST_API int STDCALL
+mono_test_marshal_fixed_buffer_unicode (FixedBufferUnicode *s)
+{
+ if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
+ return 1;
+ s->array [0] = 'E';
+ s->array [1] = 'F';
+ s->c = 'G';
+ return 0;
+}
+
+const int NSTRINGS = 6;
+//test strings
+const char *utf8Strings[] = {
+ "Managed",
+ "Sîne klâwen durh die wolken sint geslagen" ,
+ "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम्",
+ "我能吞下玻璃而不伤身体",
+ "ღმერთსი შემვედრე,შემვედრე, ნუთუ კვლა დამხსნას შემვედრე,სოფლისა შემვედრე, შემვედრე,შემვედრე,შემვედრე,შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე მზისა ელვათა კრთომაასაშემვედრე,შემვედრე,",
+ "Τη γλώσσα μου έδωσαν ελληνική",
+"\0"
+};
+
+LIBTEST_API char *
+build_return_string(const char* pReturn)
+{
+ char *ret = 0;
+ if (pReturn == 0 || *pReturn == 0)
+ return ret;
+
+ size_t strLength = strlen(pReturn);
+ ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
+ memcpy(ret, pReturn, strLength);
+ ret [strLength] = '\0';
+ return ret;
+}
+
+LIBTEST_API char *
+StringParameterInOut(/*[In,Out]*/ char *s, int index)
+{
+ // return a copy
+ return build_return_string(s);
+}
+
+LIBTEST_API void
+StringParameterRefOut(/*out*/ char **s, int index)
+{
+ char *pszTextutf8 = (char*)utf8Strings[index];
+ size_t strLength = strlen(pszTextutf8);
+ *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
+ memcpy(*s, pszTextutf8, strLength);
+ (*s)[strLength] = '\0';
+}
+
+LIBTEST_API void
+StringParameterRef(/*ref*/ char **s, int index)
+{
+ char *pszTextutf8 = (char*)utf8Strings[index];
+ size_t strLength = strlen(pszTextutf8);
+ // do byte by byte validation of in string
+ size_t szLen = strlen(*s);
+ for (size_t i = 0; i < szLen; i++)
+ {
+ if ((*s)[i] != pszTextutf8[i])
+ {
+ printf("[in] managed string do not match native string\n");
+ abort ();
+ }
+ }
+
+ if (*s)
+ {
+ marshal_free (*s);
+ }
+ // overwrite the orginal
+ *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
+ memcpy(*s, pszTextutf8, strLength);
+ (*s)[strLength] = '\0';
+}
+
+LIBTEST_API void
+StringBuilderParameterInOut(/*[In,Out] StringBuilder*/ char *s, int index)
+{
+ // if string.empty
+ if (s == 0 || *s == 0)
+ return;
+
+ char *pszTextutf8 = (char*)utf8Strings[index];
+
+ // do byte by byte validation of in string
+ size_t szLen = strlen(s);
+ for (size_t i = 0; i < szLen; i++)
+ {
+ if (s[i] != pszTextutf8[i])
+ {
+ printf("[in] managed string do not match native string\n");
+ abort ();
+ }
+ }
+
+ // modify the string inplace
+ size_t outLen = strlen(pszTextutf8);
+ for (size_t i = 0; i < outLen; i++) {
+ s[i] = pszTextutf8[i];
+ }
+ s[outLen] = '\0';
+}
+
+//out string builder
+LIBTEST_API void
+StringBuilderParameterOut(/*[Out] StringBuilder*/ char *s, int index)
+{
+ char *pszTextutf8 = (char*)utf8Strings[index];
+
+ printf ("SBPO: Receiving %s\n", s);
+ // modify the string inplace
+ size_t outLen = strlen(pszTextutf8);
+ for (size_t i = 0; i < outLen; i++) {
+ s[i] = pszTextutf8[i];
+ }
+ s[outLen] = '\0';
+}
+
+LIBTEST_API char *
+StringParameterOut(/*[Out]*/ char *s, int index)
+{
+ // return a copy
+ return build_return_string(s);
+}
+
+// Utf8 field
+typedef struct FieldWithUtf8
+{
+ char *pFirst;
+ int index;
+}FieldWithUtf8;
+
+//utf8 struct field
+LIBTEST_API void
+TestStructWithUtf8Field(struct FieldWithUtf8 fieldStruct)
+{
+ char *pszManagedutf8 = fieldStruct.pFirst;
+ int stringIndex = fieldStruct.index;
+ char *pszNative = 0;
+ size_t outLen = 0;
+
+ if (pszManagedutf8 == 0 || *pszManagedutf8 == 0)
+ return;
+
+ pszNative = (char*)utf8Strings[stringIndex];
+
+ outLen = strlen(pszNative);
+ // do byte by byte comparision
+ for (size_t i = 0; i < outLen; i++)
+ {
+ if (pszNative[i] != pszManagedutf8[i])
+ {
+ printf("Native and managed string do not match.\n");
+ abort ();
+ }
+ }
+}
+
+typedef void (* Callback2)(char *text, int index);
+
+LIBTEST_API void
+Utf8DelegateAsParameter(Callback2 managedCallback)
+{
+ for (int i = 0; i < NSTRINGS; ++i)
+ {
+ char *pszNative = 0;
+ pszNative = (char*)utf8Strings[i];
+ managedCallback(pszNative, i);
+ }
+}
+
+
+LIBTEST_API char*
+StringBuilderParameterReturn(int index)
+{
+ char *pszTextutf8 = (char*)utf8Strings[index];
+ size_t strLength = strlen(pszTextutf8);
+ char * ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
+ memcpy(ret, pszTextutf8, strLength);
+ ret[strLength] = '\0';
+
+ return ret;
+}
+
+LIBTEST_API int STDCALL
+mono_test_marshal_pointer_array (int *arr[])
+{
+ int i;
+
+ for (i = 0; i < 10; ++i) {
+ if (*arr [i] != -1)
+ return 1;
+ }
+ return 0;
+}
+
+#ifndef WIN32
+
+typedef void (*NativeToManagedExceptionRethrowFunc) (void);
+
+void *mono_test_native_to_managed_exception_rethrow_thread (void *arg)
+{
+ NativeToManagedExceptionRethrowFunc func = (NativeToManagedExceptionRethrowFunc) arg;
+ func ();
+ return NULL;
+}
+
+LIBTEST_API void STDCALL
+mono_test_native_to_managed_exception_rethrow (NativeToManagedExceptionRethrowFunc func)
+{
+ pthread_t t;
+ pthread_create (&t, NULL, mono_test_native_to_managed_exception_rethrow_thread, func);
+ pthread_join (t, NULL);
+}
+#endif