0

Purpose of this program is to control two measurement instruments through GPIB using Python.

Inst_A: controlled with CPython and PyVISA (Not yet available in IronPython).
Inst_B: controlled through DLL library provided by manufacturer; IronPython and its __import clr__

I have tried Python .NET but returns with file not found exception, whereas the same commands work in IronPython. Could it be related to this?

Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> clr.AddReference('QDInstrument')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
System.IO.FileNotFoundException: Unable to find assembly 'QDInstrument'.
   at Python.Runtime.CLRModule.AddReference(String name)

Currently, inst_b.py will run under IronPython and will repeatedly execute new Python instances along with several arguments into inst_a.py in a loop.

Is there a way to keep inst_a.py alive over the whole acquisition instead and be able to receive input data from inst_b.py? In a sense like a listener?

OS version: Windows 7 Professional SP1 amd64
Python version: 3.5.1
Python .NET version: 2.1.0 (From pip)

Thank you,
Paul.

Community
  • 1
  • 1
paul
  • 21
  • 7
  • Can you post your failing code with pythonnet? You can still use .NET 2.0+ dlls from pythonnet by setting app.config. Which version pythonnet are you using? If you end up with ironpython, then try execnet to communicate with CPython. – denfromufa May 29 '16 at 11:32
  • Here is how to set app.config: http://stackoverflow.com/a/37493025/2230844 – denfromufa May 29 '16 at 11:34
  • There are many questions here: 1)python.net problem (unclear), 2)python.net compatibility with .net 4 (unclear due to insufficient details; the general answer is yes); 3) IPC in general and between Python and IronPython in particular (too broad but okay if limit it to the ways specific to the last case). I presume that 3) is the main question. – ivan_pozdeev May 29 '16 at 15:05
  • 1
    For the former ones: a .NET 4 DLL can certainly be controlled by python.net, so your problem is something else and would do as a separate question. – ivan_pozdeev May 29 '16 at 15:09
  • 1
    Thanks for the response. I edited the original question for clarification and Python .NET exception. – paul May 29 '16 at 18:33
  • Is your .NET DLL in GAC? You need to add the path to your DLL to sys.path. Also clr.AddReference() should be without extension. – denfromufa May 29 '16 at 21:38
  • You still did not provide your pythonnet version or source. – denfromufa May 29 '16 at 21:39
  • also you can just provide full path to your assembly without extension like here: http://stackoverflow.com/a/16185372/2230844 – denfromufa May 29 '16 at 21:48
  • 1
    Well, the issue was import os; import sys; sys.path.append(os.path.dirname("__file__")) Which fixed the issue. Thank you denfromufa! – paul May 30 '16 at 04:54
  • denfromufa, how does one display all available classes that can be imported in a DLL module? – paul May 30 '16 at 05:12
  • dir(module_name), but please ask separate questions on SO. – denfromufa May 30 '16 at 05:48

2 Answers2

1

According to denfromufa and this thread, all that was required was to add path of DLL prior to adding the reference (not necessary in IronPython),

import clr
import os
import sys
sys.path.append(os.path.dirname('__file__'))

Just providing absolute path to clr.AddReference results with SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape.

Community
  • 1
  • 1
paul
  • 21
  • 7
  • Unicode error is because you tried using r"full\path\here", which conflicts with Unicode decoding, hence use double-backslash instead of escape "r" string – denfromufa May 30 '16 at 05:51
0

As per my comment, I'll focus on your last question: Preferrable ways to IPC between Python and IronPython.

First of all, any IPC involves two things:

  • data channel (pipes/streams,system-managed IPC entities,shared storage)
  • data protocol (communication procedures, data format)

The only built-in "python-specific" IPC channel that I'm aware of is multiprocessing.Queue (and derivatives). But it only works if the child process was started with the multiprocessing module - which is not applicable here.

So, you're limited to the IPC measures that the OS provides. It's too broad a topic to delve into details. At first glance, if it's sequences of data messages (rather than, say, signals) you wish to pass, pipes or sockets come to mind as one platform-agnostic and immediately apparent way.


As for data format, these can be divided into two groups:

  • serialization formats and
  • communication formats

The first group is "simple & stupid"(r) and has no constraints on objects it can save (and restore) but is inherently unsafe due to the latter. It's also inherently dependent on objects' internal representation, thus potentially incompatible between different code bases and outside a single architecture.

  • pickle is Python's built-in format of the first type. Heeding the warnings above, you can expect compatibility for built-in types if underlying primitive types are of the same length.
  • json is an example of a flexible format of the second type, struct is an example of a fixed one.

If you're using streams, you'll also need to somehow split incoming byte stream into messages. One simple way is to send <data_length> (in a platform-independent agreed-upon format) followed by <payload>, another possible one is to use separators (which must never occur in payload).

Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • Hi Ivan, the issue was me not appending the directory of .dll file to sys.path. Thank you for your insights on IPC nonetheless! – paul May 30 '16 at 04:58
  • @PaulCLou there go my efforts. The question now has changed focus entirely, so everything not related to the error in irrelevant, including your setup, "IPC inquiry", my answer and even the title - and if it stays this way, this all shall be edited out and/or deleted. That's why I suggested to ask another question rather than mutating this one. – ivan_pozdeev May 30 '16 at 13:07
  • @PaulCLou Now, the best you can do is choose which question shall ultimately be the "real one" e.g. by [accepting an answer that resolves your problem](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). – ivan_pozdeev May 30 '16 at 13:16
  • Sorry about all the confusion, I did not mean to waste your effort. I will word the questions more carefully next time. I deeply appreciate your help, it means a lot! – paul May 31 '16 at 05:11