Use .Net (C#) dll in Python script

2019-05-03 05:34发布

问题:

I'm attempting to port a simple C# command-line utility to Python. The C# program uses a custom .Net dll called foobar.dll that interfaces with some lab equipment via I2C. The usage of the dll in the C# code is as follows:

fooBar.fooProvider provider = new foobar.fooProvider()
fooBar.fooBarLib fooLib = new foobar.fooBarLib(provider, 0x80)
# used below ...
numFloat = fooLib.GetSomething()
# more python ...
fooLib.SetSomething(NumberAsAFloat)

I thought about simply using ctypes to access the dll, but I figured this wouldn't work for C#/.Net. Due to restrictions in our lab I need to use a vanilla Python distro + addon modules (i.e. not IronPython or CPython.) I looked at Python for .NET, but I'm not sure this would actually work. I'm a n00b to .Net, but have lots of experience with Java, C++ & Python. Anyone encountered this situation and a good solution before?

EDIT:

With the explanation from below in hand, I imported the clr in the python interpreter, then attempted to import the fooBar library with the following result:

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Interop.AVMCIFCLib, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'Interop.AVMCIFCLib, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null'
   at System.Signature._GetSignature(SignatureStruct& signature, Void* pCorSig, Int32 cCorSig, IntPtr fieldHandle, IntPtr methodHandle, IntPtr declaringTypeHandle)
   at System.Signature.GetSignature(SignatureStruct& signature, Void* pCorSig, Int32 cCorSig, RuntimeFieldHandle fieldHandle, RuntimeMethodHandle methodHandle, RuntimeTypeHandle declaringTypeHandle)
   at System.Signature..ctor(RuntimeMethodHandle methodHandle, RuntimeTypeHandledeclaringTypeHandle)
   at System.Reflection.RuntimeMethodInfo.get_Signature()
   at System.Reflection.RuntimeMethodInfo.FetchNonReturnParameters()
   at System.Reflection.RuntimeMethodInfo.GetParametersNoCopy()
   at System.Reflection.RuntimePropertyInfo.GetIndexParameters()
   at Python.Runtime.ClassManager.GetClassInfo(Type type)
   at Python.Runtime.ClassManager.CreateClass(Type type)
   at Python.Runtime.ClassManager.GetClass(Type type)
   at Python.Runtime.ModuleObject.GetAttribute(String name, Boolean guess)
   at Python.Runtime.ModuleObject.LoadNames()
   at Python.Runtime.ImportHook.__import__(IntPtr self, IntPtr args, IntPtr kw)

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

And then the interpreter crashes. This looks like a badly built dll, correct?

回答1:

Python for .NET works really well, and you can execute .NET code from within Python. IronPython works well too, although the other way around. You can think of Python for .NET as an extension of CPython that can execute .NET code, while IronPython is an extension of the CLR allowing to execute Python code. Since your needs dictate you to use a vanilla Python, Python for .NET should work. And to note, the vanilla python distribution is CPython in most cases.