10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python C# データ連携

Last updated at Posted at 2021-10-24

こんにちは、本日はPythonとC#間でデータのやり取りをする方法を紹介します。
使用する技術は「共有メモリ」です。

動作の仕組み

  1. Pythonで名前付き共有メモリの作成
  2. C#でPythonで作成した共有メモリを開く
  3. 相互にデータの読み書きを実施

環境

Windows10
※名前付き共有メモリを利用するにはWindowsOSを利用する必要があります。

pythonでの名前付き共有メモリはWindowsでしか利用できません。。。
「tagname」の引数が共有メモリの名前です。

image.png

Linux、Macなどでは無名の共有メモリを利用するか、
ファイルベースの共有メモリを利用するしかできません。

ソースコード

今回のプログラムはPythonで共有メモリの1WORD目の値をインクリメントしていき、
C#側でその値を読み取っていきます。

Python 共有メモリの作成&書き込み

MMapTest.py
import mmap
import time

WORD_SIZE = 2
MMAP_FILE_NAME = "MAP_TEST"

def mmapWriteShort(adr:int, data):
    '''
    指定のアドレスに値を書き込む(Shortデータ)
    '''
    global mm
    
    try:
        ddata = int(data)
        bytes = ddata.to_bytes(WORD_SIZE, 'little',signed=True)

        for i in range(WORD_SIZE):
            mm[adr*WORD_SIZE + i] = bytes[i]
    except Exception as e:
        pass

def mmapReadShort(adr:int):
        """指定のアドレスの値を読み込む(Shortデータ)

        Args:
            adr : Shared memory address
        """    
        try:
            mm.seek(adr*WORD_SIZE)
            bytes = mm.read(WORD_SIZE)
            val = int.from_bytes(bytes, 'little',signed=True)
            mm.seek(0)
            return val
        except Exception as e:
            return None

if __name__ == "__main__":
    # 名前付き共有メモリの作成
    # 1つ目の引数を−1にすることで、ファイルなしの共有メモリを生成できる
    # (tagname=Noneの場合は無名共有メモリとなる)
    mm = mmap.mmap(-1, 13, tagname=MMAP_FILE_NAME)

    cnt = 0
    
    # アドレス0番地の値をインクリしていく
    while True:
        cnt += 1
        mmapWriteShort(0, cnt)
        #print(mmapReadShort(0))
        time.sleep(1)

C# 共有メモリの読み出し

Form1.cs
using System;
using System.Text;
using System.Windows.Forms;
using System.IO.MemoryMappedFiles;

namespace SharedMemTest
{
    public partial class Form1 : Form
    {
        MemoryMappedFile _share_mem;
        MemoryMappedViewAccessor _accessor;

        int READ_ADR = 0;
        const string MMAP_FILE_NAME = "MAP_TEST";

        public Form1()
        {
            InitializeComponent();

            // Pythonで作成した名前付き共有メモリを開く
            this._share_mem = MemoryMappedFile.OpenExisting(MMAP_FILE_NAME);
            this._accessor = this._share_mem.CreateViewAccessor();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;

            byte[] data = new byte[2];
            int readsize = _accessor.ReadArray<byte>(READ_ADR, data, 0, data.Length);
            short shortData = BitConverter.ToInt16(data, 0);

            label1.Text = shortData.ToString();

            timer1.Enabled = true;
        }
    }
}

注意書き

エラー処理は実装していないので、適宜追加してください。

ファイル無しの共有メモリの場合は、
アプリ終了時に共有メモリの値がクリアされるので、
最後の状態を覚えておきたい場合などはファイル有りの共有メモリの利用を検討ください。

共有メモリ参考記事

Python 共有メモリ

Python mmap 使い方

C# 共有メモリ

C# 共有メモリを利用する

更新履歴

  • 2021/10/24 初版
10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?