[Python.NET] Parameter marshalling question

Slide <[email protected]> Fri, 20 Aug 2021 09:39:28 -0700
Newsgroups gmane.comp.python.dotnet
Message-ID <CAPiUgVdWvx3u1GKF=TOe3oURAYDvZLZpxn=0TXUmzq0m-KgkyQ@mail.gmail.com>
--===============7658363973634481449==
Content-Type: multipart/alternative; boundary="00000000000047682f05ca005065"

--00000000000047682f05ca005065
Content-Type: text/plain; charset="UTF-8"

I have the following method defined in my application that I am trying to
call from Python using PythonNET


Snippet

public IEnumerable<byte> ReadBuffer(ulong address, int size, out int readCount)


The address can be anything in the range of 0x0_0000_0000 - 0x1_XXXX_XXXX,
when I call this using a value that is less than 0x1_0000_0000 (e.g.,
0x0_01d00_0000) I get an error that the value an Int32 when a UInt64 is
expected, so I created an override that takes an Int32 as the first
parameter and the function works when using values less than 0x1_0000_0000,
so far so good. However, when I try and call the function with an address
>= 0x1_0000_0000 I get the following exception.

System.AggregateException: One or more errors occurred. --->
System.ArgumentException: Expected UInt64, got Int32 in method
System.Collections.Generic.IEnumerab
le`1[System.Byte] ReadBuffer(UInt64, Int32, Int32 ByRef) --->
Python.Runtime.PythonException: Expected UInt64, got Int32
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.ArgumentException: Expected UInt64, got
Int32 in method System.Collections.Generic.IEnumerable`1[System.Byte]
ReadBuffer(UInt64
, Int32, Int32 ByRef) ---> Python.Runtime.PythonException: Expected UInt64,
got Int32
--- End of inner exception stack trace ---<---

---> (Inner Exception #1) System.ArgumentException: value too large to
convert in method System.Collections.Generic.IEnumerable`1[System.Byte]
ReadBuffer(Int32,
Int32, Int32 ByRef) ---> Python.Runtime.PythonException: value too large to
convert
--- End of inner exception stack trace ---<---

It seems like the checks in converter.cs will choose Int32 even if the
value is longer that 32-bits (since PyInt is also true for larger than
32-bit values).

Snippet

if (value == Runtime.PyIntType){    result = int32Type;
    return true;}
if (value == Runtime.PyLongType){
    result = int64Type;
    return true;}

So, I am confused how I can get the correct method resolution and the
correct type.

Can anyone shed any light on this?

Regards,

Alex

-- 
Website: http://earl-of-code.com

--00000000000047682f05ca005065
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I have the following method defined in my application that=
 I am trying to call from Python using PythonNET<div><br></div><div><br></d=
iv><div>Snippet<pre style=3D"font-family:&quot;Cascadia Code&quot;;font-siz=
e:12px;color:rgb(218,218,218);background:rgb(39,40,34)"><span style=3D"colo=
r:rgb(102,217,239)">public</span>=C2=A0<span style=3D"color:rgb(248,248,242=
)">IEnumerable</span><span style=3D"color:gainsboro">&lt;</span><span style=
=3D"color:rgb(102,217,239)">byte</span><span style=3D"color:gainsboro">&gt;=
</span>=C2=A0<span style=3D"color:rgb(220,220,170)">ReadBuffer</span><span =
style=3D"color:gainsboro">(</span><span style=3D"color:rgb(102,217,239)">ul=
ong</span>=C2=A0<span style=3D"color:rgb(156,220,254)">address</span><span =
style=3D"color:gainsboro">,</span>=C2=A0<span style=3D"color:rgb(102,217,23=
9)">int</span>=C2=A0<span style=3D"color:rgb(156,220,254)">size</span><span=
 style=3D"color:gainsboro">,</span>=C2=A0<span style=3D"color:rgb(102,217,2=
39)">out</span>=C2=A0<span style=3D"color:rgb(102,217,239)">int</span>=C2=
=A0<span style=3D"color:rgb(156,220,254)">readCount</span><span style=3D"co=
lor:gainsboro">)</span>
</pre><div><br></div><div>The address can be anything in the range of 0x0_0=
000_0000 - 0x1_XXXX_XXXX, when I call this using a value that is less than =
0x1_0000_0000 (e.g., 0x0_01d00_0000) I get an error that the value an Int32=
 when a UInt64 is expected, so I created an override that takes an Int32 as=
 the first parameter and the function works when using values less than 0x1=
_0000_0000, so far so good. However, when I try and call the function with =
an address &gt;=3D 0x1_0000_0000 I get the following exception.=C2=A0</div>=
<div><br></div><div><div style=3D"display:inline-block;white-space:pre;back=
ground-color:rgb(0,0,0);font-family:&quot;Cascadia Code PL&quot;,monospace;=
font-size:9pt;padding:4px"><span style=3D"color:rgb(255,255,255)">System.Ag=
gregateException: One or more errors occurred. ---&gt; System.ArgumentExcep=
tion: Expected UInt64, got Int32 in method System.Collections.Generic.IEnum=
erab<br>le`1[System.Byte] ReadBuffer(UInt64, Int32, Int32 ByRef) ---&gt; Py=
thon.Runtime.PythonException: Expected UInt64, got Int32<br>   --- End of i=
nner exception stack trace ---<br>   --- End of inner exception stack trace=
 ---<br>---&gt; (Inner Exception #0) System.ArgumentException: Expected UIn=
t64, got Int32 in method System.Collections.Generic.IEnumerable`1[System.By=
te] ReadBuffer(UInt64<br>, Int32, Int32 ByRef) ---&gt; Python.Runtime.Pytho=
nException: Expected UInt64, got Int32<br>   --- End of inner exception sta=
ck trace ---&lt;---<br><br>---&gt; (Inner Exception #1) System.ArgumentExce=
ption: value too large to convert in method System.Collections.Generic.IEnu=
merable`1[System.Byte] ReadBuffer(Int32,<br> Int32, Int32 ByRef) ---&gt; Py=
thon.Runtime.PythonException: value too large to convert<br>   --- End of i=
nner exception stack trace ---&lt;---</span></div><div><br></div><div>It se=
ems like the checks in converter.cs will choose Int32 even if the value is =
longer that 32-bits (since PyInt is also true for larger than 32-bit values=
).</div><div><br></div><div>Snippet<pre style=3D"font-family:&quot;Cascadia=
 Code&quot;;font-size:12px;color:rgb(218,218,218);background:rgb(39,40,34)"=
><span style=3D"color:rgb(216,160,223)">if</span>=C2=A0<span style=3D"color=
:gainsboro">(</span><span style=3D"color:rgb(248,248,242)">value</span>=C2=
=A0<span style=3D"color:rgb(180,180,180)">=3D=3D</span>=C2=A0<span style=3D=
"color:rgb(248,248,242)">Runtime</span><span style=3D"color:rgb(180,180,180=
)">.</span><span style=3D"color:rgb(248,248,242)">PyIntType</span><span sty=
le=3D"color:gainsboro">)</span>
<span style=3D"color:gainsboro">{</span>
<span style=3D"color:rgb(248,248,242)">    result</span>=C2=A0<span style=
=3D"color:rgb(180,180,180)">=3D</span>=C2=A0<span style=3D"color:rgb(248,24=
8,242)">int32Type</span><span style=3D"color:gainsboro">;</span>
=C2=A0   r<span style=3D"color:rgb(216,160,223)">eturn</span>=C2=A0<span st=
yle=3D"color:rgb(102,217,239)">true</span><span style=3D"color:gainsboro">;=
</span>
<span style=3D"color:gainsboro">}</span>

<span style=3D"color:rgb(216,160,223)">if</span>=C2=A0<span style=3D"color:=
gainsboro">(</span><span style=3D"color:rgb(248,248,242)">value</span>=C2=
=A0<span style=3D"color:rgb(180,180,180)">=3D=3D</span>=C2=A0<span style=3D=
"color:rgb(248,248,242)">Runtime</span><span style=3D"color:rgb(180,180,180=
)">.</span><span style=3D"color:rgb(248,248,242)">PyLongType</span><span st=
yle=3D"color:gainsboro">)</span>
<span style=3D"color:gainsboro">{</span>
=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"color:rgb(248,248,242)">result</span=
>=C2=A0<span style=3D"color:rgb(180,180,180)">=3D</span>=C2=A0<span style=
=3D"color:rgb(248,248,242)">int64Type</span><span style=3D"color:gainsboro"=
>;</span>
=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"color:rgb(216,160,223)">return</span=
>=C2=A0<span style=3D"color:rgb(102,217,239)">true</span><span style=3D"col=
or:gainsboro">;</span>
<span style=3D"color:gainsboro">}</span></pre></div><div>So, I am confused =
how I can get the correct method resolution and the correct type.=C2=A0</di=
v><div><br></div><div>Can anyone shed any light on this?</div><div><br></di=
v><div>Regards,</div><div><br></div><div>Alex</div><div><br></div>-- <br><d=
iv dir=3D"ltr" class=3D"gmail_signature" data-smartmail=3D"gmail_signature"=
>Website:=C2=A0<a href=3D"http://earl-of-code.com" target=3D"_blank">http:/=
/earl-of-code.com</a></div></div></div></div>

--00000000000047682f05ca005065--

--===============7658363973634481449==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
PythonNet mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/pythonnet.python.org/
Member address: [email protected]

--===============7658363973634481449==--