1

Windows システム コール (ReadFile() や WriteFile() など) を行う ActiveX (COM) DLL があります。私の GUI (Python または C#) は、メインの GUI スレッドで DLL のインスタンスを作成します。ただし、スレッドから呼び出しを行うには、C# または Python の使用に関係なく、各スレッドで DLL の新しいインスタンスを作成する必要があります。(ちなみに、元のインスタンスは C# のスレッドから呼び出すことができますが、これはメイン スレッドをブロックします。Python でこれを行うと、GUI がクラッシュします。)スレッドで DLL の新しいインスタンスを作成しないようにする方法はありますか?

元の DLL インスタンスを使用する理由: DLL を使用すると、HID マイクロコントローラーに接続できます。DLL は、マイクロコントローラに 1 つの排他ハンドルのみを許可するオプションを提供します。GUI 設計者がこのオプションを選択した場合 (特定の状況で必要になります)、DLL の 1 つのインスタンスのみが接続を確立できるため、2 番目の DLL インスタンスは期待どおりに機能しません。

4

2 に答える 2

1

ActiveX / COMコンポーネントを作成する場合、コンポーネントのスレッドモデルを指定できます。たとえば、「コンパートメント化」することができます。どちらを選択するかに応じて、ActiveX/COMがリクエストのシリアル化を処理します。

ActiveX / COMコンポーネントを複数回「開く」場合(スレッドモデルによって異なりますか?)、実際には1つのインスタンスのみが作成されます。

Win32com.client.Dispatch( "。")を使用してActiveX/COMコンポーネントを「開く」ことを前提としています。

また、pythoncom.CoInitialize()とCoUninitialize()の呼び出しのペアを忘れないでください。

それらが実際に何をするかについてのグーグル。

特定のActiveX/COMコンポーネントを変更できず、そのスレッドモデルが受け入れられない場合は、すべての「アウトバウンド」呼び出しを、モニター「インターフェイス」を備えた1つの専用Pythonスレッドでラップできます。

これは、私がかつて同様の状況に直面したときに書いたコードの概要です。

class Driver(threading.Thread):
    quit = False  # graceful exit
    con = None
    request = None
    response = None

    def __init__(self, **kw):
        super(Driver, self).__init__(**kw)
        self.setDaemon(True)  # optional, helps termination
        self.con = threading.Condition()
        self.request = None
        self.response = None

    def run(self):
        pythoncom.CoInitialize()
        handle = win32com.client.Dispatch("SomeActiveX.SomeInterface")
        try:
            with self.con:
                while not self.quit:
                    while not self.request: self.con.wait()                    # wait for work
                    method, args = self.request
                    try: self.response = getattr(handle, method)(*args), None  # buffer result
                    except Exception, e: self.response = None, e               # buffer exception
                    self.con.notifyAll()                                       # result ready
        finally:
            pythoncom.CoUninitialize()

    def call(method, *args):
        with self.con:
            while self.request: self.con.wait()       # driver is busy
            self.request = method, args
            self.con.notifyAll()                      # driver can start
            while not self.response: self.con.wait()  # wait for driver
            rv, ex = self.response
            self.request = self.response = None       # free driver
            self.con.notifyAll()                      # other clients can continue
            if ex: raise ex
            else: return rv
于 2012-06-12T13:41:34.383 に答える
1

私は Phyton を使用したことはありませんが、C# の場合は、静的パブリック プロパティとして ActiveX を含むヘルパー クラスを作成することをお勧めします。メイン スレッドで ActiveX を作成し、そこからすべてのスレッドが必要に応じてアクセスします。

于 2012-06-08T16:22:53.647 に答える