[Mono-list] Mono/.NET delegate incompatibility

Piers Haken piersh@friskit.com
Thu, 19 Dec 2002 14:25:23 -0800


This is a multi-part message in MIME format.

------_=_NextPart_001_01C2A7AD.85C5DB74
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

you're right, in order to remain compatible, mono should use stdcall
convention by default on win32. (existing code, etc...)

piers.

-----Original Message-----
From: J. Perkins [mailto:jason@379.com]
Sent: Thursday, December 19, 2002 11:42 AM
To: J. Perkins
Cc: 'Mono-L'
Subject: RE: [Mono-list] Mono/.NET delegate incompatibility


Hang on a minute, I answered this too soon. I'm not talking about
calling a DLL function. [DllImport] works just fine on both Windows and
Linux. I am talking about a callback function, from unmanaged -> managed
code. That is, a C# delegate passed to and called from unmanaged code
via a function pointer. Here's a usenet thread on the subject:

 http://makeashorterlink.com/?C417214D2

The problem described in this thread is reversed for Mono: the callback
must use the cdecl convention. Because of this, there is no way to write
a C function that can call a delegate under both .NET and Mono. If I do
this:

  int SomeCFunction(int (__stdcall *callback)(int, int, int))
  {  return callback(1,2,3); }

...it will corrupt the stack when run under Mono on Windows. If I use
cdecl instead:

  int SomeCFunction(int (*callback)(int, int, int))
  { return callback(1,2,3); }

...it will corrupt the stack when run under .NET. Maybe I'm missing
something (quite possible), but it appears that Mono must use __stdcall
for delegates on Windows.

I'll give you guys a chance to sanity check my rambling. If it holds up
I will file a bug.=20

Jason
379


> > I guess the default calling convention in mono is cdecl.  According
to
> > MSDN, the default calling convention for dllimport should be stdcall
> > (which IMHO really only makes sense on windows).
> >=20
> > You could try setting the CallingConvention property on the
DllImport to
> > cdecl.




_______________________________________________
Mono-list maillist  -  Mono-list@ximian.com
http://lists.ximian.com/mailman/listinfo/mono-list

------_=_NextPart_001_01C2A7AD.85C5DB74
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Diso-8859-1">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version =
6.0.4417.0">
<TITLE>RE: [Mono-list] Mono/.NET delegate incompatibility</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=3D2>you're right, in order to remain compatible, mono =
should use stdcall convention by default on win32. (existing code, =
etc...)</FONT></P>

<P><FONT SIZE=3D2>piers.</FONT>
</P>

<P><FONT SIZE=3D2>-----Original Message-----</FONT>

<BR><FONT SIZE=3D2>From: J. Perkins [<A =
HREF=3D"mailto:jason@379.com">mailto:jason@379.com</A>]</FONT>

<BR><FONT SIZE=3D2>Sent: Thursday, December 19, 2002 11:42 AM</FONT>

<BR><FONT SIZE=3D2>To: J. Perkins</FONT>

<BR><FONT SIZE=3D2>Cc: 'Mono-L'</FONT>

<BR><FONT SIZE=3D2>Subject: RE: [Mono-list] Mono/.NET delegate =
incompatibility</FONT>
</P>
<BR>

<P><FONT SIZE=3D2>Hang on a minute, I answered this too soon. I'm not =
talking about</FONT>

<BR><FONT SIZE=3D2>calling a DLL function. [DllImport] works just fine =
on both Windows and</FONT>

<BR><FONT SIZE=3D2>Linux. I am talking about a callback function, from =
unmanaged -&gt; managed</FONT>

<BR><FONT SIZE=3D2>code. That is, a C# delegate passed to and called =
from unmanaged code</FONT>

<BR><FONT SIZE=3D2>via a function pointer. Here's a usenet thread on the =
subject:</FONT>
</P>

<P><FONT SIZE=3D2>&nbsp;<A =
HREF=3D"http://makeashorterlink.com/?C417214D2">http://makeashorterlink.c=
om/?C417214D2</A></FONT>
</P>

<P><FONT SIZE=3D2>The problem described in this thread is reversed for =
Mono: the callback</FONT>

<BR><FONT SIZE=3D2>must use the cdecl convention. Because of this, there =
is no way to write</FONT>

<BR><FONT SIZE=3D2>a C function that can call a delegate under both .NET =
and Mono. If I do</FONT>

<BR><FONT SIZE=3D2>this:</FONT>
</P>

<P><FONT SIZE=3D2>&nbsp; int SomeCFunction(int (__stdcall =
*callback)(int, int, int))</FONT>

<BR><FONT SIZE=3D2>&nbsp; {&nbsp; return callback(1,2,3); }</FONT>
</P>

<P><FONT SIZE=3D2>...it will corrupt the stack when run under Mono on =
Windows. If I use</FONT>

<BR><FONT SIZE=3D2>cdecl instead:</FONT>
</P>

<P><FONT SIZE=3D2>&nbsp; int SomeCFunction(int (*callback)(int, int, =
int))</FONT>

<BR><FONT SIZE=3D2>&nbsp; { return callback(1,2,3); }</FONT>
</P>

<P><FONT SIZE=3D2>...it will corrupt the stack when run under .NET. =
Maybe I'm missing</FONT>

<BR><FONT SIZE=3D2>something (quite possible), but it appears that Mono =
must use __stdcall</FONT>

<BR><FONT SIZE=3D2>for delegates on Windows.</FONT>
</P>

<P><FONT SIZE=3D2>I'll give you guys a chance to sanity check my =
rambling. If it holds up</FONT>

<BR><FONT SIZE=3D2>I will file a bug. </FONT>
</P>

<P><FONT SIZE=3D2>Jason</FONT>

<BR><FONT SIZE=3D2>379</FONT>
</P>
<BR>

<P><FONT SIZE=3D2>&gt; &gt; I guess the default calling convention in =
mono is cdecl.&nbsp; According to</FONT>

<BR><FONT SIZE=3D2>&gt; &gt; MSDN, the default calling convention for =
dllimport should be stdcall</FONT>

<BR><FONT SIZE=3D2>&gt; &gt; (which IMHO really only makes sense on =
windows).</FONT>

<BR><FONT SIZE=3D2>&gt; &gt; </FONT>

<BR><FONT SIZE=3D2>&gt; &gt; You could try setting the CallingConvention =
property on the DllImport to</FONT>

<BR><FONT SIZE=3D2>&gt; &gt; cdecl.</FONT>
</P>
<BR>
<BR>
<BR>

<P><FONT SIZE=3D2>_______________________________________________</FONT>

<BR><FONT SIZE=3D2>Mono-list maillist&nbsp; -&nbsp; =
Mono-list@ximian.com</FONT>

<BR><FONT SIZE=3D2><A =
HREF=3D"http://lists.ximian.com/mailman/listinfo/mono-list">http://lists.=
ximian.com/mailman/listinfo/mono-list</A></FONT>
</P>

</BODY>
</HTML>
------_=_NextPart_001_01C2A7AD.85C5DB74--