コンテンツにスキップ

チュートリアル:DLL連携機能編

DLL連携機能で使用するDLLを作成するためのコンパイル環境の構築方法を解説します。
コンパイル環境にはMinGW(MSYS2)とVisual Studio(MSVC)の2つの方法をご紹介します。

Info

必要オプション:Digital Palette


サンプルコード

本チュートリアルでは、以下のサンプルコードを使用します。
回路上の抵抗Rを定電力10Wの抵抗としてふるまわせる例です。

#include <Windows.h>
#include <math.h>
#include <stdbool.h>

#define EXPORT __declspec(dllexport)

typedef void *SContext;
typedef double (*OutputFunc)(SContext context, const char *sym, const char *type, const char *mode);
typedef void (*SetParamFunc)(SContext context, const char *sym, const char *par, double val);

static HMODULE handle = NULL;
static OutputFunc output = NULL;
static SetParamFunc setparam = NULL;

EXPORT bool scideamStart(SContext context) {
    handle = LoadLibraryA("ScideamFunc.dll");
    output = (OutputFunc)GetProcAddress(handle, "Output");
    setparam = (SetParamFunc)GetProcAddress(handle, "SetParam");
    return true;
}

EXPORT void scideamStop(SContext context) { FreeLibrary(handle); }

EXPORT void scideamUpdate(SContext context) {
    const double voltage = output(context, "R", "V", "AVE");
    const double POWER = 10;
    double resistance = voltage * voltage / POWER;
    resistance = fmax(resistance, 1e-3);
    setparam(context, "R", "Value", resistance);
}

scideamUpdateにメインサイクル毎の処理を記述します。
今回の例では、Rの電圧平均値を取得し、定電力10Wとなるように抵抗値()を計算してRのパラメータに設定しています。


1 MinGW(MSYS2)によるコンパイル環境構築

1.1 MSYS2のダウンロード

MSYS2のホームページにアクセスし、msys2-x86_64のインストーラーを選択してダウンロードします。

fig


1.2 MSYS2のインストール

ダウンロードしたインストーラーを実行します。
すべての設定はデフォルトのままNextで進めてください。

fig

fig

fig

fig

インストールが完了したらFinishをクリックします。

fig


1.3 GCCのインストール

インストール完了時にRun MSYS2 now.にチェックを入れていた場合は、自動でMSYS2のターミナルが起動します。
起動していない場合は、WindowsのスタートメニューからMSYS2 UCRT64を検索して起動してください。

fig

MSYS2のターミナルが開いたら、以下のコマンドを実行してGCCをインストールします。

pacman -S mingw-w64-ucrt-x86_64-gcc

fig

Proceed with installation? [Y/n]と表示されたらYを入力してインストールを続行します。

インストールが完了したら、以下のコマンドでGCCが正しくインストールされたことを確認します。

gcc --version

fig


1.4 パスを通す

コマンドプロンプトやPowerShellからGCCを使用できるように、環境変数PATHにMSYS2のパスを追加します。

Win+Rを押して「ファイル名を指定して実行」を開き、sysdm.cplと入力してOKをクリックします。

fig

「システムのプロパティ」が開いたら、詳細設定タブの環境変数(N)...をクリックします。

fig

「システム環境変数」のPathを選択し、編集(I)...をクリックします。

fig

新規(N)をクリックし、C:\msys64\ucrt64\binを追加してOKをクリックします。

fig

Note

MSYS2のインストール先をカスタマイズしている場合は、C:\msys64の部分を実際のインストール先のパスに置き換えてください。

設定後、PowerShellなどでgcc --versionが実行できることを確認してください。

fig


1.5 コンパイル

コマンドプロンプトまたはPowerShellでplugin.cを保存したフォルダに移動し、以下のコマンドでDLLをコンパイルします。

gcc -shared -o plugin.dll plugin.c

-sharedオプションを指定することでDLLとして出力され、-oオプションで出力ファイル名を指定します。


2 Visual Studio(MSVC)によるコンパイル環境構築

2.1 Visual Studioのダウンロード

Visual Studioのダウンロードページからインストーラーをダウンロードします。

fig


2.2 Visual Studioのインストール

ダウンロードしたインストーラーを実行すると、Visual Studio Installerが起動します。

fig

ワークロードの選択画面でC++によるデスクトップ開発にチェックを入れ、インストールを実行します。

Note

C++によるデスクトップ開発のインストールには約8.75GBのディスク容量が必要です。

fig


2.3 DLLプロジェクトの作成

インストールが完了したら、Visual Studioを起動します。

fig

スタート画面から新しいプロジェクトの作成(N)を選択します。

fig

検索欄にdllと入力し、ダイナミック リンク ライブラリ (DLL)を選択して次へ(N)をクリックします。

fig

プロジェクト名と保存場所を設定して作成(C)をクリックします。
ここではプロジェクト名をpluginとしています。

fig

プロジェクトが作成され、DLLのテンプレートコードが表示されます。

fig


2.4 ソースファイルの追加

ソリューションエクスプローラーのソースファイルを右クリックし、追加(D)新しい項目(W)...を選択します。

fig

ファイル名を入力して追加をクリックします。
デフォルトでは拡張子が.cppになっていますが、.cに変更して問題ありません。

fig

作成したファイルにサンプルコードを貼り付けて保存します。
保存するとコードの左側に緑色のバーが表示されます。

fig


2.5 プリコンパイル済みヘッダーの無効化

追加したソースファイルはC言語で記述しているため、プリコンパイル済みヘッダーを無効にする必要があります。

ソリューションエクスプローラーでプロジェクト名を右クリックし、プロパティ(R)を選択します。

fig

構成(C)すべての構成に変更し、C/C++プリコンパイル済みヘッダーを開きます。プリコンパイル済みヘッダープリコンパイル済みヘッダーを使用しないに変更し、適用(A)をクリックしてOKで閉じます。

fig

Note

構成(C)すべての構成に変更せずに設定した場合、現在選択中の構成(既定ではDebug)にのみ設定が適用されます。後述の2.6ではRelease構成でビルドするため、すべての構成を選択せずに設定するとビルド時にプリコンパイル済みヘッダーの設定が反映されずエラーになります。


2.6 ビルド

ツールバーの構成をReleaseに変更します。

fig

メニューバーのビルド(B)ソリューションのビルド(B)を選択します。

fig

出力ウィンドウにビルド成功のメッセージが表示されれば完了です。

fig

ソリューションエクスプローラーでプロジェクトを右クリックし、エクスプローラーで開く(X)から出力先フォルダを確認できます。

fig

プロジェクト作成時に指定した名前で.dllが生成されます。今回の例ではplugin.dllです。

fig


3 Scideamでの解析

コンパイルしたDLLをScideamに取り込み、解析を実行する流れを解説します。

3.1 回路作成

サンプルコードに対応する回路を作成します。
交流電源VAC(100[V]、50[Hz])と直流電源VDC(200[V])を直列に接続し、抵抗R(初期値1[ohm])に印加する回路です。

fig

Note

抵抗のシンボル名は、サンプルコード内で参照しているシンボル名(R)と一致させる必要があります。
異なるシンボル名にする場合は、サンプルコードのoutputおよびsetparamの第2引数も合わせて変更してください。

Note

抵抗値は1[ohm]に設定していますが、DLLにより毎サイクル更新されるため、初期値は任意の値で構いません。


3.2 出力変数の設定

DLLから参照する出力変数を設定します。

Configurations editorを開き、Outputを選択します。

fig

+系列追加をクリックしてSelect outputダイアログを開きます。
RVoltageCurrentにチェックを入れ、モードをDefault (Average)に設定してOKをクリックします。

fig

ChartR/Voltage/AverageR/Current/Averageが追加されます。

fig


3.3 演算の設定

電力(電圧×電流)を表示するための演算系列を追加します。

演算系列を別チャートに表示するために、+チャートの追加をクリックして新しいチャートを追加します。

fig

続いて、追加したChartを選択した状態で、+演算系列追加をクリックします。

fig

Select outputダイアログが開いたら、以下のように設定してOKをクリックします。

  • 名前: PR
  • 出力変数:
    • o[0]: R/Voltage/Average
    • o[1]: R/Current/Average
  • : o[0]*o[1]

fig

追加したChartPRが追加されます。

fig


3.4 DLL設定

コンパイルしたDLLをScideamに取り込みます。

Configurations editorScriptDLLを選択します。

fig

+をクリックし、コンパイルしたplugin.dllを選択します。

fig


3.5 解析設定

ツールバーからTransientを選択し、以下のように設定します。

  • 終了時間: 0.03

fig


3.6 解析

Transientボタンをクリックして解析を実行します。
解析が完了すると、PRが約10[W]に制御されていることが確認できます。

fig


4 デバッグ方法

DLL内部で計算した変数は、そのままではScideam側から参照できません。
そこで、メイン回路とは独立したダミー素子を配置し、setparamでその素子のパラメータに内部変数を書き込むことで、波形として変数の値を確認する方法を紹介します。
ここでは、3章の回路を例にscideamUpdate内で計算しているresistanceの値を可視化します。

4.1 デバッグ用回路の追加

3章で作成した回路に、デバッグ用のダミー回路を追加します。
直流電源VDC1(初期値5[V])と抵抗R1(1[ohm])を直列に接続したループを、メイン回路とは接続しないように配置します(下図の赤枠部分)。

fig

Note

デバッグ用回路は、それ単体で回路として成立している(閉ループになっている)必要があります。
また、VDC1の初期値は後述のDLLにより毎サイクル上書きされるため任意の値で構いません。R1の値も任意で構いません。


4.2 サンプルコードの修正

scideamUpdateVDC1のパラメータを更新する行を追加します。

EXPORT void scideamUpdate(SContext context) {
    const double voltage = output(context, "R", "V", "AVE");
    const double POWER = 10;
    double resistance = voltage * voltage / POWER;
    resistance = fmax(resistance, 1e-3);
    setparam(context, "R", "Value", resistance);
    setparam(context, "VDC1", "Value", resistance);  // add
}

追加した1行により、resistanceの値がVDC1の電圧値として書き込まれます。
修正後はDLLを再コンパイルし、Scideamに取り込み直してください。


4.3 出力変数の設定

VDC1の電圧を観測するための出力変数を追加します。

Configurations editorOutput+チャートの追加をクリックして新しいチャートを追加し、+系列追加VDC1VoltageをモードDefault (Average)で追加します。

fig


4.4 解析

解析を再実行すると、VDC1:V:AVEのチャートにresistanceの時間変化が表示されます。

fig

Note

グラフの縦軸の単位はVと表示されますが、実際にはDLLから書き込まれたresistanceの値(単位は[ohm])が表示されています。