差分

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

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

5,561 バイト追加, 2019年7月26日 (金) 16:46
= インストール =最新かと合わせて以下のコマンドを実行します。<syntaxhighlight lang="bash">pacman -Syupacman -S sudo</syntaxhighlight>久しぶりにやったら、すっかり忘れていたので覚書…
= sudoを使用できるユーザーを指定する = C++のDLLプロジェクト作成 ==visudoで「/etc/sudoers」ファイルを編集します。まず、C++のDLLを作成するときの注意点…作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。<br/>以下の様に追加すれば「root」と同じ権限で実行できるようになります。[[ファイル:CShapeToCppDll-005.jpg]]
ファイルを開く
<syntaxhighlight lang="bash">visudo /etc/sudoers</syntaxhighlight>
あと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。<br/>
[[ファイル:CShapeToCppDll-001.jpg]]<br/>
追記前
<syntaxhighlight lang="text">##
## User privilege specification
##
root ALL=(ALL) ALL</syntaxhighlight>
追記後<syntaxhighlight lang="text" highlight="5">#### User privilege specification##root ALL=(ALL) ALL[myuser] ALL=(ALL) ALL</syntaxhighlight>([myuser]は自分のユーザーIDに置き換えてください)空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.cpp」「CppDll.h」「CppDll.def」を追加したよ。
= sudoにプロキシ設定を引き継ぐ =
sudoしたら外部にアクセスできなくなったとかあるかと思います。<br/>
sudoにプロキシ設定が引き継がれないために、外部にアクセスできなくなっています。<br/>
なので、プロキシ設定を引き継ぐ設定をします。
ファイルを開くそしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。<br/>(DebugとReleaseでそれぞれ設定する必要があるんだよ。)<syntaxhighlight lang="bash"br/>visudo /etc/sudoers[[ファイル:CShapeToCppDll-002.jpg]]<br/syntaxhighlight>
ファイルの最後に以下を追記します。== DLLのコード ===== ヘッダーファイル(*.h) ===<syntaxhighlight lang="bashcpp">Defaults env_keep += #ifndef DLLAPI#define DLLAPI extern "http_proxy https_proxy ftp_proxy HTTP_PROXY HTTPS_PROXY FTP_PROXYC"</syntaxhighlight>__declspec(dllimport)#endif
= 参考サイト =DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);[https://wiki.archlinux.jp/index.php/%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E8%A8%AD%E5%AE%9A#sudo_.E3.81.A7.E3.82.82.E3.83.97.E3.83.AD.E3.82.AD.E3.82.B7.E3.82.92.E4.BD.BF.E3.81.86 プロキシ設定 - ArchWiki]<br/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:ArchLinuxC♯]][[Category:sshC++]]{{DISPLAYTITLE[[Category:sudoのインストール}}dll]]

案内メニュー