この記事は EtherCATについて語る Advent Calendar 2019 の11日目です。
昨日は@nonNoiseさんの EtherCAT開発方法 フレーム編(ライトまで) でした。
今日はオープンソースのEtherCATマスターであるSOEMをWindows上の.NETアプリで使う方法を解説します。
(1) SOEMをDLL化するためAPIをC言語で定義する
まず、SOEMをDLL化して外部から呼ぶ出せるようにするため、APIをC言語で定義する。soemlib.c という名前でソースファイルを作成し、必要なAPI関数を定義する。DLLのAPI関数の定義には、__declspec(dllexport) と __stdcall というキーワードを付ける。一例を以下に示す。(2019/12/19 修正)
#include "ethercat.h" int __stdcall soem_open(char* nif) { int ret = ec_init(nif); return ret; }
また、API関数をsoemlib.defというファイルに列挙する。 (2019/12/19 追記)
(2) CMakeを使ってSOEMのDLLをビルドする
Windows環境でのCMakeによるSOEMのビルド方法についてはまず以前の記事を参照。
SOEM/CMakeLists.txt の最後のほうに1行追加する。DLLのソースを置くサブディレクトリの追加である。親ディレクトリ名がlinuxになっているが気にしない。
if(BUILD_TESTS) add_subdirectory(test/linux/slaveinfo) add_subdirectory(test/linux/eepromtool) add_subdirectory(test/linux/simple_test) add_subdirectory(test/linux/soemlib) # ←この行を追加 endif()
SOEM/test/linux/soemlib/CMakeLists.txt を下記の内容で作成する。これがDLLをビルドするレシピである。add_library()で SHARED を指定することで共有ライブラリがビルドされる。Windowsでは共有ライブラリとはすなわちDLLである。
set(SOURCES soemlib.c soemlib.def) add_library(soemlib SHARED ${SOURCES}) target_link_libraries(soemlib soem) install(TARGETS soemlib DESTINATION lib)
(1)で作成したsoemlib.cを SOEM/test/linux/soemlib/ に置く。そしてCMakeによるビルドを実行する。ビルドが成功すると、SOEM/build/test/linux/soemlib/soemlib.dll が生成される。
(3) DLLをラップするクラスをC#で作成する
作成したDLLを.NETアプリから使うため、C#でラッパーを作成する。EtherCAT.cs という名前でソースファイルを作成しクラスを定義する。DLLが提供するAPI関数をC#で使うには、DllImport属性を使い、DLLファイル名とAPI関数名を指定する。一例を下記に示す。
using System.Runtime.InteropServices; // DllImport (中略) // EtherCATラッパークラス class EtherCAT { (中略) // 開く [DllImport("soemlib.dll", EntryPoint = "soem_open")] extern public static int open(string nif);