プログラムの違い

こんにちは mtj です。

プログラムと一概に言ってもそれを使用する場でかなりの意識の変化が必要になります。

  • 組み込み系
  • ネイティブのアプリ
  • WEBアプリ
  • サーバーサイドのプログラム

上記のそれぞれで考える事、注意する事がばらばらで同じ動作をさせようとしてもそれぞれで難易度が異なったりします。
また使用する言語、フレームワークの向き不向きもあるためかなり広い範囲での知識が必要になるように感じます

個別にどれをやっていたからどれが簡単等も少なく 基本はその分野について知っているかになると感じました
大まかなくくりの中にもどのネイティブ環境か フレームワークかCPUかだったり細かい違いがあるためさらに細かい分野知識も必要になりソフトが改めて奥が深いと感じます。

AI等も流行ってくるのでそれらも応用できるようになっていくのが時代の流れかもしれません。

C#13.0(.NET 9.0)のLockクラスとC#のlock構文について

C#のlockについて少し調べた際にたまたま知ったのですが、
C#13.0(.NET 9.0, 2024/11リリース)にてLockクラスが追加されたようです。
Lock クラス (System.Threading) | Microsoft Learn


// 上記記事からの引用となります
public sealed class ExampleDataStructure {
    private readonly Lock _lockObj = new();

    public void Modify() {
        lock (_lockObj) {
            // Critical section associated with _lockObj
        }

        using (_lockObj.EnterScope()) {
            // Critical section associated with _lockObj
        }

        _lockObj.Enter();
        try {
            // Critical section associated with _lockObj
        }
        finally { _lockObj.Exit(); }

        if (_lockObj.TryEnter()) {
            try {
                // Critical section associated with _lockObj
            }
            finally { _lockObj.Exit(); }
        }
    }
}

このLockクラスは従来のlock構文のロック対象objectのように宣言し、
従来のlock構文で使用できるほか、using構文でも使用でき、
またロック試行など細かな制御も可能なようです。

lock構文に対して、
不満(謎のobjectを用意する必要がある、構文が特殊、細かい制御が不可)があったので、
便利そうで良いなと思いました。

しかし、このLockクラスが追加されたのはどうも利便性向上のためではないらしく、
以下の2記事によるとパフォーマンス向上のためらしいです。
Lock クラス | ++C++; // 未確認飛行 C ブログ
【.NET 9.0】System.Threading.Lock のパフォーマンス #C# – Qiita

任意のオブジェクトに対してlockできるのはオーバーヘッドが大きい
とのことで、Qiitaの記事によると5%ほどパフォーマンス向上するとのことです。

そこで知ったのですが、そもそもC#には排他制御を司るMonitorクラスが存在し、
lock構文はMonitorクラスにより排他制御の糖衣構文のようです。
(以前からやろうと思えば細かい制御もできたんですね。。。)
マルチスレッド – C# によるプログラミング入門 | ++C++; // 未確認飛行 C

その糖衣構文がLockクラスの追加により、
ロック対象に今回のLockクラスのインスタンスに指定した場合に
Monitor使用のコードの代わりにLockによるコードへの置換に変更されるとのことです。

なので、C#13.0では基本的にはlock構文にLockクラスを併用するのが良いかと思われます。
以上、Lockクラスとlock構文についてでした。

※それともう一つ、数値型の単純な演算をアトミックに行えるInterlockedクラスの存在も
 上記のQiita記事内で初めて知りました。
 色々と便利なクラスがあったんですね。。。

I/Oユニット

先日の案件でSUS株式会社のI/OユニットSiOtを使用しました。

いつもはコンテックのI/Oユニットを使用していますが、今回は配線が楽なのと、メーカからスイッチBOXも購入出来るのでSiOtを使用してみました。
I/Oの配線はコネクタ式なので、購入したスイッチBOXを差し込むだけで配線完了です。

PCソフトからイーサネット通信で入力/出力が可能になっています。コマンドは簡単なのですぐに実装可能です。
通信時間が遅いので、同じ出力状態の場合は再送しないようになど細工は必要です。

コンテックと比較してメリットもデメリットもあるので、案件によって使い分けようと思います。
たぶん、PLCと接続する場合はコンテックが良く、ランプ・スイッチ・センサなどに直接接続する場合はSUSが良いと思われます。

テストプレイ

こんにちはmtjです。

何かしらのソフトを触っていると なんでこんな使いにくい だったり おかしい動作があるんだって思う時があると思います。
開発の中では簡単な部分は完成してしまっていると通過点になってしまっておりそのまま開発が続けられる可能性が高いと思います。
その通過点に使いにくい部分があったりする事で上のような明らかにおかしいような動作が残されたりするのではないかなと思います。

大事なのは実際に使ってみてのテストになるのですが
それもテスト者がどの程度効率化、使いにくさ、わかりにくさを認識するかになると思われます。

結果としてはなかなかそういう事を防ぐのは難しいと思いました

Visual Studio Setup Projectにてexeファイル追加によりビルドが失敗する際の対処

今回は題の通りで、
ソフトが使用する別ソフトのexeファイルをインストーラーに同梱する必要が生じたため、
ソフトのインストーラーを作成するSetup Projectにexeファイルを追加したのですが、
それによりSetup Projectのビルドが失敗するようになりました。
その対処として、exeファイルをzipに圧縮して追加するようにしました。

以下経緯です。

失敗の原因は、追加した覚えのないdllファイルでした。
どうもSetup Projectにexeファイルを追加すると、
そのexeの依存するdllがすべて自動で追加されるようです。

追加されたファイルはプロパティウィンドウにて除外の設定が可能なのですが、
除外しても失敗は解決できませんでした。
(正確には、VS上でのビルドは成功するようになったのですが、
 運用としてはスクリプトから言語設定の構成を切り替えて2回ビルドを行う必要があり、
 そのスクリプトでは依然として失敗しました。
 StackOverFlowの投稿で見かけたのですが、
 構成の切り替えにより除外した依存関係が自動で有効化されるらしいです。)

dllが追加されないように(※)exeをzipに圧縮して追加し、
ソフトの起動時にzipを解凍する処理を実装しました。
※拡張子の変更も試しましたが、
 変更してもしっかり実行ファイルだと認識しdllが追加されてしまいました。

結局、dllの追加により何故失敗するかはエラーメッセージからもはっきりわからなかったのですが、
ソフト自身の依存するdllと同名の異なるバージョンのdllが追加されていたので、
バッティングが原因だったのではないかと推測しています。

Setupプロジェクトの動作が重いのも相まって解決に少し手間取ってしまったのですが、
リリース作業の運用は変更する必要なく解決できたので良かったです。

ライセンス用のUSBドングル

先日の案件でユーザごとにライセンス認証を行うためにUSBドングル対応を行いました。

市販のUSBドングルを使用する方法ではなく、普通のUSBメモリで認証を行う機能を社内ライブラリに実装しました。
USBメモリの固有情報+秘密キーから作成した認証用ファイルをUSBメモリに入れておくことで実現しています。

簡単な方法ですが、十分な効果があります。

弊社が作成するソフトは工場で使用するものが大半なのでライセンス管理は普段行っていませんが、今後必要な場合には、この方法で簡単に対応出来るようになりました。

ソフト開発での提案

こんにちはmtjです。

ソフトの受託開発は基本的にはお客さんの仕様通り作る事が仕事ですが
明らかに操作フローが不明だったり 違和感あるような内容は少し細かく踏み込んだりします。

依頼側が詳しければきちんと教えてくれたりしてくれます。
特に詳しくない場合UIもフローもだいたいなんとなくだったりします

そういうときにこちらが意識して問い合わせる内容は以下のような内容です。

  • 誰が
  • どの程度の頻度で
  • どういった目的で触るか
  • 触ったり 情報を得た結果、操作後はどのようなフローか

上記の情報からその立場で仮想的に使ってみてUXを検討します。

誰が
操作者の知識量を想定します。
システムに慣れた人かどうかか特定の一部の人だけかでUIのわかりやすさ等を検討します。

どの程度の頻度 どの機能をどの程度の頻度で触るかで使いやすさの検討を行います。

どういった目的で触るか
主に画面操作時に見せる内容、入力等を検討するため

結果、操作後の動作
操作結果の見せる情報、物理的に出力する内容の検討のため

上記を意識し 提案をしていく事で良いシステムが出来上がると思います。

普段生活している時も意識してシステムを見ることで普段作っている側では発見できないような事も発見できるかもしれませんね。

C#にて内部クラスからprivateなメンバへアクセス

C#にてprivateなメンバを別のクラスにのみ公開したいことがあります。
この1つの実現方法として、
特定のクラスが自身と密接に関係する場合以外は推奨されないと思いますが、
特定のクラスを内部クラスとして定義すれば可能だと知りました。
内部クラスはごくまれにしか定義しないので、今更知りました。
Stateパターンってどう実装するのが良いのだろうと思っていたのですが、
Stateのクラスを外部に公開しないなら内部クラスで良かったのですね。
地味に疑問だったので晴れて良かったです。

/// <summary> partialテストクラス </summary>
internal class SampleClass {
  /// <summary> 状態インスタンス </summary>
    private IState State { get; set; }
    /// <summary> 何かの数 </summary>
    private int Count { get; set; }
    
    /// <summary> 具象状態クラス </summary>
    internal class ConcreteState : IState {
        /// <summary> 何かする </summary>
        public void Do(SampleClass parent) {
            tester.Count++;
        }
    }
}

/// <summary> 状態インタフェース </summary>
internal interface IState {
    /// <summary> 何かする </summary>
    void Do(SampleClass tester);
}

※詳しくないのですが、
 Javaだとprotectedがサブクラスだけでなく同一package内ならアクセス可能らしいので、
 packageをちゃんと定義すれば可能なのかもしれません。

VB6で使用できるDLLをC#で作成

先日の案件で、依頼元が作成しているVB6ソフトに通信機能を実装してほしいとのご要望がありました。
しかし、今さらVB6での開発は行いたくないため、C#で通信機能を実装したDLLを作成し、VB6からDLLを
呼び出してもらうようにしました。

この結果、弊社のC#共通ライブラリを使用して効率良く開発が行えました。
特にVB6はスレッドが使用出来ないことがネックになるのですが、C#でDLLを作成することでスレッドも使用できますので、
通信の受信待ちなどをVB6のスレッドを気にせず、別スレッドで非同期に待てるので、とても実装が楽になります。

今回、初めてVB6で使用できるCOM形式のC#DLLを作成しましたので、調査必要な箇所も多かったですが、
詰まることもほぼ無く開発出来ました。

工場の設備などでは年期のはいったVB6ソフトがよく使われています。改造依頼も良くあります。
このような依頼内容の場合は、今後もこの方法が有効であると分かりました。

AI出力のプログラム

こんにちはmtjです。

最近といっても数年前からですがAIでプログラム出力が盛んになってきました。
AIのプログラムはしっかり読んで覚えるべきかどうかが度々議論になっている気がします。

自分は自分の価値を高めたいのなら見るべきだし、作業としてさっさと終わらせるだけなら見なくていいという意見です。
自分の場合は基本読んで理解します、読まずにAI作成プログラムを導入するのはリスクが高いです
見ない人の気持ちも上に書いた通り さっさと終わらせたいならそうすればいいという感じです

上のような話はプログラムをコピペで作るだけという話にも似ているような気がします
読んで理解して書くより 動いている動作をコピペして目的通り動けばいいという考えですが
早いといえば早いけど コードで見たら酷い物になっていると思います、酷いものと理解できるのであればそもそもそういうレベルでコピペなんてしないと思いますが

AIを読まない人の話も コピペでプログラムを作る人の話も システム制作の話を深堀りしていった時にからっぽになってしまうのではないかと思います
自分が面接をしていたら そんな怪しい人は取れない気がします

よく言われていますが 今後はシステム開発はAIを使っている人 使われている人を見極めるスキルが必要になるのかなと感じます
使われている人の場合はシステムがうまく行っている場合は問題ないように見え、速度も早いですが 爆弾を含んでいるような人材になると思います
AIで上手くいかない場合の対処が難しくなり 復旧等も時間がかかり最悪復旧不可のような自体もあるかもしれません。

システムを完成できない人よりも見極めが難しくなるかもしれませんね