差分

ナビゲーションに移動 検索に移動

C♯のモジュールからC++のDLLを呼び出してみる

3,981 バイト追加, 2019年7月26日 (金) 16:46
USB3.0のポートを1つ持っているLattepandaですが、物によってUSB3.0が機能していない場合があるようです<ref name="LP_forum_USB30" />。<br/>確認してみようかと思います。久しぶりにやったら、すっかり忘れていたので覚書…
== USB3.0で接続できているかの確認 C++のDLLプロジェクト作成 ==参考サイトにもありますが、以下のコマンドを実行します。<syntaxhighlight lang="bash">lsusbまず、C++のDLLを作成するときの注意点…作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。<br/syntaxhighlight>すると、以下の様な結果が得られます。<syntaxhighlight lang="text">Bus 002 Device 002: ID 0b95:1790 ASIX Electronics Corp. AX88179 Gigabit EthernetBus 002 Device 001[[ファイル: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 003: ID 0bda:8152 Realtek Semiconductor Corp. Bus 001 Device CShapeToCppDll-005: ID 0411:02cc BUFFALO INC. (formerly MelCo., Inc.) Bus 001 Device 004: ID 2341:8036 Arduino SA Leonardo (CDC ACM, HID)Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. HubBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub</syntaxhighlight>私の場合、「AX88179」チップ搭載のLANアダプタであるBUFFALOの「LUA4-U3-AGTE-BK」を接続しているので、1行目と4行目にその類の結果が得られています。<br/>これだけでも、2行目を見れば「Linux Foundation 3.0 root hub」と表示されているので、大丈夫と言えば大丈夫なのですが、ちゃんとLANアダプタがUSB3.0のポートに接続されているかも確認します。jpg]]
この結果を踏まえた上で、以下のコマンドを実行します。<syntaxhighlight lang="bash">lsusb -t</syntaxhighlight>すると、以下の様な結果が得られます。<syntaxhighlight lang="text">/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
|__ Port 1: Dev 2, If 0, Class=Vendor Specific Class, Driver=ax88179_178a, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/7p, 480M
|__ Port 3: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 4, If 2, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 1: Dev 4, If 0, Class=Communications, Driver=cdc_acm, 12M
|__ Port 1: Dev 4, If 1, Class=CDC Data, Driver=cdc_acm, 12M
|__ Port 2: Dev 5, If 0, Class=Mass Storage, Driver=usb-storage, 480M
|__ Port 4: Dev 3, If 0, Class=Vendor Specific Class, Driver=r8152, 480M</syntaxhighlight>「Bus 02」の「Dev 1」に「5000M」と出ているので「USB3.0」のポートだとわかります。<br/>「lsusb」の結果でもそのように出ていました。
その配下にある「Dev 2(Bus 02)」に「Driver=ax88179_178a」と表示されていることから、これがUSBあと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。<br/>[[ファイル:CShapeToCppDll-LANアダプタとわかります。001.jpg]]<br/>
どうやら、ちゃんとUSB-LANアダプタはUSB3.0で接続されているようです。
== もし「2空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.0 root hub」となっていたら… ==BIOSをアップデートすると直るようです<ref name="LP_forum_USB30" />。cpp」「CppDll.h」「CppDll.def」を追加したよ。
== 参考サイト ==
[https://blog.goo.ne.jp/takuminews/e/6ea03871680f0d004591493984610974 Linuxで見るとUSB3.0のインターフェイスが実はUSB2接続だった - 情報技術の四方山話]
== 脚注 ==そしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。<referencesbr/>(DebugとReleaseでそれぞれ設定する必要があるんだよ。)<ref name="LP_forum_USB30"br/>[https[ファイル://www.lattepanda.com/topicCShapeToCppDll-f10t1306002.html [RESOLVED]USB 3.0 connection problem - LattePanda Forumjpg]]<br/ref></references>
== DLLのコード ===== ヘッダーファイル(*.h) ===<syntaxhighlight lang="cpp">#ifndef DLLAPI#define DLLAPI extern "C" __declspec(dllimport)#endif DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);</syntaxhighlight> === コードファイル(*.cpp) ===<syntaxhighlight lang="cpp">#define DLLAPI #include "CppDll.h" DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2){ return p_Number1 + p_Number2;}</syntaxhighlight> === モジュール定義ファイル(*.def) ===<syntaxhighlight lang="text">LIBRARY CppDll EXPORTS _Sum</syntaxhighlight> == C♯のプロジェクト作成 ==ほとんどそのまま作るんだけど…ソリューションのコンパイル対策をしておくよ。 === ビルドイベントの設定 ===C++のDLLはソリューションフォルダ直下の「Debug」や「Release」フォルダにDLLが格納されてしまうんだ。そうすると、デバッグするときにDLLが見つからないので、ビルドイベントを使ってコピーしてしまうよ。以下のように設定してね。(「Release」コンパイルするまでは「Release」フォルダがないのでコメントアウトしているよ)<br/>[[ファイル:CShapeToCppDll-004.jpg]]<br/> === プロジェクトの依存関係の設定 ===コピーするにもちゃんとリコンパイルされた資源をコピーしないといけないので、プロジェクトの依存関係を設定することで、ビルドの順番を設定するよ。<Br/>ソリューションエクスプローラーからC♯のプロジェクトを右クリックして「ビルド依存関係」→「プロジェクト依存関係」を選択してね。<br/>「依存関係」タブの依存先にC++のプロジェクトが表示されているはずだから、チェックを入れてOKボタンをクリックしてね。 == C♯のコード ==MVVMモデルでサンプルを作ったからビューモデルが入っているけど…DLLを呼ぶには必要ないから無視してね。=== モデル ===<syntaxhighlight lang="C#">using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes; //追加using System.Runtime.InteropServices; namespace CSharpToCDLL{ /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { /// <summary> /// DLLの関数定義 /// </summary> /// <param name="p_Number1">数値1</param> /// <param name="p_Number2">数値2</param> /// <returns>合計</returns> [DllImport("CppDll.dll")] private extern static Int32 _Sum(Int32 p_Number1,Int32 p_Number2);  /// <summary> /// 標準のコンストラクタ /// </summary> public MainWindow() { InitializeComponent(); }  /// <summary> /// ボタンクリックイベントハンドラ /// </summary> /// <param name="sender">イベント送信元</param> /// <param name="e">イベント情報</param> private void Button_Click(object sender, RoutedEventArgs e) { //DLLの関数を呼び出す Int32 l_Result = _Sum(300, 500);  //計算結果の表示 MessageBox.Show("計算結果:" + l_Result.ToString()); } }}</syntaxhighlight> === ビュー ===<source lang="xml"><Window x:Class="CSharpToCDLL.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="77.056" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="5"/> <RowDefinition Height="24"/> <RowDefinition/> <RowDefinition Height="5"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="5"/> <ColumnDefinition/> <ColumnDefinition Width="5"/> <ColumnDefinition Width="75"/> <ColumnDefinition Width="5"/> </Grid.ColumnDefinitions> <Label Grid.Row="1" Grid.Column="1" Content="{Binding Label_Content}"/> <Button Grid.Row="1" Grid.Column="3" Content="実行" Click="Button_Click"/> </Grid></Window></source>=== ビューモデル ===<source lang="csharp">using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; //追加using System.ComponentModel; namespace CSharpToCDLL{ class MainWindowViewModel : INotifyPropertyChanged { /// <summary> /// ラベル表示用変数 /// </summary> private String m_Label_Content;  /// <summary> /// ラベル表示文字列 /// </summary> public String Label_Content { set { this.m_Label_Content = value; this.OnPropertyChanged("Label_Content"); } get { return this.m_Label_Content; } }  /// <summary> /// プロパティ変更イベントハンドラ /// </summary> public event PropertyChangedEventHandler PropertyChanged;  /// <summary> /// プロパティ変更通知 /// </summary> /// <param name="p_PropertyName">プロパティ名</param> public void OnPropertyChanged(String p_PropertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(p_PropertyName)); } } }}</source> [[Category:C♯]][[Category:DebianC++]][[Category:Lattepandadll]]

案内メニュー