I am trying to use a .NET dll in Python. In a .NET language the method requires passing it 2 arrays by reference which it then modifies:
public void GetItems(
out int[] itemIDs,
out string[] itemNames
)
How can I use this method in Python using the Python for .NET module?
Edit: Forgot to mention this is in CPython not IronPython.
Additional info. When I do the following:
itemIDs = []
itemNames = []
GetItems(itemIDs, itemNames)
I get an output like:
(None, <System.Int32[] at 0x43466c0>, <System.String[] at 0x43461c0>)
Do I just need to figure out how to convert these back into python types?
PythonNet doesn't document this quite as clearly as IronPython, but it does almost the same thing.
So, let's look at the IronPython documentation for
ref
andout
parameters:There are examples for both. But to tailor it to your specific case:
Or, if you really want:
CPython using PythonNet does basically the same thing. The easy way to do
out
parameters is to not pass them and accept them as extra return values, and forref
parameters to pass the input values as arguments and accept the output values as extra return values. Just like IronPython's implicit solution. (Except that avoid
function withref
orout
parameters always returnsNone
before theref
orout
arguments, even if it wouldn't in IronPython.) You can figure it out pretty easily by inspecting the return values. So, in your case:Meanwhile, the fact that these happen to be arrays doesn't make things any harder. As the docs explain, PythonNet provides the iterable interface for all
IEnumerable
collections, and the sequence protocol as well forArray
. So, you can do this:And the
Int32
andString
objects will be converted to nativeint
/long
andstr
/unicode
objects just as if they were returned directly.If you really want to explicitly convert these to native values, you can.
map
or a list comprehension will give you a Python list from any iterable, including a PythonNet wrapper around anArray
or otherIEnumerable
. And you can explicitly make along
orunicode
out of anInt32
orString
if you need to. So:But I don't see much advantage to doing this, unless you need to, e.g., pre-check all the values before using any of them.
I have managed to use the method bool XferData(ref byte[] buf, ref int len) from C# library CyUSB.dll with the following code:
Hope this helps someone.