ページ「X11vnc/Debian9.9」と「C♯のモジュールからC++のDLLを呼び出してみる」の間の差分

提供: とある社畜の頭脳整理
(ページ間の差分)
ナビゲーションに移動 検索に移動
 
 
1行目: 1行目:
デスクトップ環境を使用している場合、リモートでデスクトップを使用したい場合があります。<br/>
+
久しぶりにやったら、すっかり忘れていたので覚書…
今回はX11vncを使用して、リモートでデスクトップに接続してみようと思います。
 
  
= X11vncのインストール =
+
== C++のDLLプロジェクト作成 ==
下記コマンドを実行して、X11vncをインストールします。
+
まず、C++のDLLを作成するときの注意点…
 +
作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。<br/>
 +
[[ファイル:CShapeToCppDll-005.jpg]]
  
<syntaxhighlight lang="bash">sudo apt-get install x11vnc</syntaxhighlight>
 
(確認されたら「y」を押してください)<br/>
 
だぁ~っとなってインストールが完了します。
 
<syntaxhighlight lang="bash">test@debian:~$ sudo apt-get install x11vnc
 
パッケージリストを読み込んでいます... 完了
 
依存関係ツリーを作成しています               
 
状態情報を読み取っています... 完了
 
以下の追加パッケージがインストールされます:
 
  libtcl8.6 libtk8.6 libvncclient1 libvncserver1 tcl tcl8.6 tk tk8.6 x11vnc-data
 
提案パッケージ:
 
  tcl-tclreadline
 
以下のパッケージが新たにインストールされます:
 
  libtcl8.6 libtk8.6 libvncclient1 libvncserver1 tcl tcl8.6 tk tk8.6 x11vnc x11vnc-data
 
アップグレード: 0 個、新規インストール: 10 個、削除: 0 個、保留: 3 個。
 
3,503 kB のアーカイブを取得する必要があります。
 
この操作後に追加で 10.3 MB のディスク容量が消費されます。
 
続行しますか? [Y/n] y
 
取得:1 http://ftp.jp.debian.org/debian stretch/main amd64 libtcl8.6 amd64 8.6.6+dfsg-1+b1 [985 kB]
 
取得:2 http://ftp.jp.debian.org/debian stretch/main amd64 libtk8.6 amd64 8.6.6-1+b1 [754 kB]
 
取得:3 http://ftp.jp.debian.org/debian stretch/main amd64 libvncclient1 amd64 0.9.11+dfsg-1.3~deb9u1 [141 kB]
 
取得:4 http://ftp.jp.debian.org/debian stretch/main amd64 libvncserver1 amd64 0.9.11+dfsg-1.3~deb9u1 [210 kB]
 
取得:5 http://ftp.jp.debian.org/debian stretch/main amd64 tcl8.6 amd64 8.6.6+dfsg-1+b1 [123 kB]
 
取得:6 http://ftp.jp.debian.org/debian stretch/main amd64 tcl amd64 8.6.0+9 [5,468 B]
 
取得:7 http://ftp.jp.debian.org/debian stretch/main amd64 tk8.6 amd64 8.6.6-1+b1 [71.8 kB]
 
取得:8 http://ftp.jp.debian.org/debian stretch/main amd64 tk amd64 8.6.0+9 [5,506 B]
 
取得:9 http://ftp.jp.debian.org/debian stretch/main amd64 x11vnc-data all 0.9.13-2+deb9u1 [216 kB]
 
取得:10 http://ftp.jp.debian.org/debian stretch/main amd64 x11vnc amd64 0.9.13-2+deb9u1 [992 kB]
 
  
~ 中略 ~
+
あと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。<br/>
 +
[[ファイル:CShapeToCppDll-001.jpg]]<br/>
  
libc-bin (2.24-11+deb9u4) のトリガを処理しています ...
 
man-db (2.7.6.1-2) のトリガを処理しています ...
 
gnome-menus (3.13.3-9) のトリガを処理しています ...
 
libtcl8.6:amd64 (8.6.6+dfsg-1+b1) を設定しています ...
 
libtk8.6:amd64 (8.6.6-1+b1) を設定しています ...
 
tcl8.6 (8.6.6+dfsg-1+b1) を設定しています ...
 
tk8.6 (8.6.6-1+b1) を設定しています ...
 
tcl (8.6.0+9) を設定しています ...
 
tk (8.6.0+9) を設定しています ...
 
x11vnc (0.9.13-2+deb9u1) を設定しています ...
 
libc-bin (2.24-11+deb9u4) のトリガを処理しています ...</syntaxhighlight>
 
  
= 自動ログインの設定 =
+
空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.cpp」「CppDll.h」「CppDll.def」を追加したよ。
X11vncですが、基本的にログインしている状態でないと、リモートで接続することができません。<br/>
 
なので、画面からリモートで接続したいユーザーで自動ログインするようにします。
 
  
PC本体にディスプレイ及びキーボード・マウスを接続して、ログイン画面を表示させます。<br/>
 
[[ファイル:Debian-x11vnc-001.png | 400px]]<br/>
 
  
パスワードを入力して、「サインイン」をクリックまたはエンターキーを押します。<br/>
+
そしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。<br/>
[[ファイル:Debian-x11vnc-002.png | 400px]]<br/>
+
(DebugとReleaseでそれぞれ設定する必要があるんだよ。)<br/>
 +
[[ファイル:CShapeToCppDll-002.jpg]]<br/>
  
デスクトップが表示されたら、画面右上の下向き矢印「▼」をクリックします。<br/>
+
== DLLのコード ==
[[ファイル:Debian-x11vnc-003.png | 400px]]<br/>
+
=== ヘッダーファイル(*.h) ===
 +
<syntaxhighlight lang="cpp">
 +
#ifndef DLLAPI
 +
#define DLLAPI extern "C" __declspec(dllimport)
 +
#endif
  
ログインしているユーザーが表示されるので、それをクリックします。<br/>
+
DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);
[[ファイル:Debian-x11vnc-004.png | 400px]]<br/>
+
</syntaxhighlight>
  
「アカウント設定」をクリックします。<br/>
+
=== コードファイル(*.cpp) ===
[[ファイル:Debian-x11vnc-005.png | 400px]]<br/>
+
<syntaxhighlight lang="cpp">
 +
#define DLLAPI
  
「ロック解除」をクリックします。<br/>
+
#include "CppDll.h"
[[ファイル:Debian-x11vnc-006.png | 400px]]<br/>
 
  
パスワードの入力が促されるので、ユーザーに対応したパスワードを入力します。<br/>
+
DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2)
[[ファイル:Debian-x11vnc-007.png | 400px]]<br/>
+
{
 +
return p_Number1 + p_Number2;
 +
}
 +
</syntaxhighlight>
  
「認証」ボタンをクリックします。<br/>
+
=== モジュール定義ファイル(*.def) ===
[[ファイル:Debian-x11vnc-008.png | 400px]]<br/>
+
<syntaxhighlight lang="text">
 +
LIBRARY CppDll
  
ロックが解除されるので、「自動ログイン」をクリックして、「オン」にします。<br/>
+
EXPORTS
[[ファイル:Debian-x11vnc-009.png | 400px]]<br/>
+
_Sum
 
+
</syntaxhighlight>
設定の確認をするために、ウインドウ左上の左向き矢印「<」をクリックします。<br/>
 
[[ファイル:Debian-x11vnc-010.png | 400px]]<br/>
 
 
 
「ユーザー」をクリックします。自動ログインがオンになっていればOKです。<br/>
 
[[ファイル:Debian-x11vnc-011.png | 400px]]<br/>
 
 
 
最後に「<strong><u>ログインした状態のまま</u></strong>」にしておきます。
 
  
= X111vncのパスワード設定 =
+
== C♯のプロジェクト作成 ==
認証なしで画面が見れてしまうのは危険(特にログインしっぱなし)なので、パスワードを設定します。<br/>
+
ほとんどそのまま作るんだけど…ソリューションのコンパイル対策をしておくよ。
以下のコマンドを実行します。
 
<syntaxhighlight lang="bash">x11vnc -storepasswd</syntaxhighlight>
 
  
すると、パスワードの入力が2回求められるので、2回とも同じパスワードを入力します。<br/>
+
=== ビルドイベントの設定 ===
また、ホームディレクトリの「.vnc」ディレクトリに保存するか問われるので、「y」を入力します<br/>
+
C++のDLLはソリューションフォルダ直下の「Debug」や「Release」フォルダにDLLが格納されてしまうんだ。そうすると、デバッグするときにDLLが見つからないので、ビルドイベントを使ってコピーしてしまうよ。以下のように設定してね。(「Release」コンパイルするまでは「Release」フォルダがないのでコメントアウトしているよ)<br/>
<syntaxhighlight lang="bash">test@debian:~$ x11vnc -storepasswd
+
[[ファイル:CShapeToCppDll-004.jpg]]<br/>
Enter VNC password:
 
Verify password:   
 
Write password to /home/test/.vnc/passwd?  [y]/n y
 
Password written to: /home/test/.vnc/passwd
 
test@debian:~$ </syntaxhighlight>
 
  
= X11vncの起動 =
+
=== プロジェクトの依存関係の設定 ===
最小限のオプションで起動してみます。<br/>
+
コピーするにもちゃんとリコンパイルされた資源をコピーしないといけないので、プロジェクトの依存関係を設定することで、ビルドの順番を設定するよ。<Br/>
以下のコマンドを実行します。
+
ソリューションエクスプローラーからC♯のプロジェクトを右クリックして「ビルド依存関係」→「プロジェクト依存関係」を選択してね。<br/>
<syntaxhighlight lang="bash">x11vnc -display :0 -rfbauth ~/.vnc/passwd</syntaxhighlight>
+
「依存関係」タブの依存先にC++のプロジェクトが表示されているはずだから、チェックを入れてOKボタンをクリックしてね。
上記は、「ディスプレイ番号0(5900ポート)で『~/.vnc/passwd』に設定されたパスワード認証で起動」という意味です。<br/>
 
以下のようなメッセージが出て、カーソルが点滅して戻ってこなかったら起動しています(色々言われていますが…www)。<br/>
 
<syntaxhighlight lang="bash">24/06/2019 14:50:39 passing arg to libvncserver: -rfbauth
 
24/06/2019 14:50:39 passing arg to libvncserver: /home/test/.vnc/passwd
 
24/06/2019 14:50:39 x11vnc version: 0.9.13 lastmod: 2011-08-10  pid: 2472
 
24/06/2019 14:50:39 Using X display :0
 
24/06/2019 14:50:39 rootwin: 0x280 reswin: 0x1400001 dpy: 0x84e7bfe0
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 ------------------ USEFUL INFORMATION ------------------
 
24/06/2019 14:50:39 X DAMAGE available on display, using it for polling hints.
 
24/06/2019 14:50:39  To disable this behavior use: '-noxdamage'
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39  Most compositing window managers like 'compiz' or 'beryl'
 
24/06/2019 14:50:39  cause X DAMAGE to fail, and so you may not see any screen
 
24/06/2019 14:50:39  updates via VNC.  Either disable 'compiz' (recommended) or
 
24/06/2019 14:50:39  supply the x11vnc '-noxdamage' command line option.
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 Wireframing: -wireframe mode is in effect for window moves.
 
24/06/2019 14:50:39  If this yields undesired behavior (poor response, painting
 
24/06/2019 14:50:39  errors, etc) it may be disabled:
 
24/06/2019 14:50:39    - use '-nowf' to disable wireframing completely.
 
24/06/2019 14:50:39    - use '-nowcr' to disable the Copy Rectangle after the
 
24/06/2019 14:50:39      moved window is released in the new position.
 
24/06/2019 14:50:39  Also see the -help entry for tuning parameters.
 
24/06/2019 14:50:39  You can press 3 Alt_L's (Left "Alt" key) in a row to
 
24/06/2019 14:50:39  repaint the screen, also see the -fixscreen option for
 
24/06/2019 14:50:39  periodic repaints.
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 XFIXES available on display, resetting cursor mode
 
24/06/2019 14:50:39  to: '-cursor most'.
 
24/06/2019 14:50:39  to disable this behavior use: '-cursor arrow'
 
24/06/2019 14:50:39  or '-noxfixes'.
 
24/06/2019 14:50:39 using XFIXES for cursor drawing.
 
24/06/2019 14:50:39 GrabServer control via XTEST.
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 Scroll Detection: -scrollcopyrect mode is in effect to
 
24/06/2019 14:50:39  use RECORD extension to try to detect scrolling windows
 
24/06/2019 14:50:39  (induced by either user keystroke or mouse input).
 
24/06/2019 14:50:39  If this yields undesired behavior (poor response, painting
 
24/06/2019 14:50:39  errors, etc) it may be disabled via: '-noscr'
 
24/06/2019 14:50:39  Also see the -help entry for tuning parameters.
 
24/06/2019 14:50:39  You can press 3 Alt_L's (Left "Alt" key) in a row to
 
24/06/2019 14:50:39  repaint the screen, also see the -fixscreen option for
 
24/06/2019 14:50:39  periodic repaints.
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 XKEYBOARD: number of keysyms per keycode 10 is greater
 
24/06/2019 14:50:39  than 4 and 100 keysyms are mapped above 4.
 
24/06/2019 14:50:39  Automatically switching to -xkb mode.
 
24/06/2019 14:50:39  If this makes the key mapping worse you can
 
24/06/2019 14:50:39  disable it with the "-noxkb" option.
 
24/06/2019 14:50:39  Also, remember "-remap DEAD" for accenting characters.
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 X FBPM extension not supported.
 
24/06/2019 14:50:39 X display is capable of DPMS.
 
24/06/2019 14:50:39 --------------------------------------------------------
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 Default visual ID: 0x21
 
24/06/2019 14:50:39 Read initial data from X display into framebuffer.
 
24/06/2019 14:50:39 initialize_screen: fb_depth/fb_bpp/fb_Bpl 24/32/3200
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 X display :0 is 32bpp depth=24 true color
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 Autoprobing TCP port
 
24/06/2019 14:50:39 Autoprobing selected TCP port 5900
 
24/06/2019 14:50:39 Autoprobing TCP6 port
 
24/06/2019 14:50:39 Autoprobing selected TCP6 port 5900
 
24/06/2019 14:50:39 listen6: bind: Address already in use
 
24/06/2019 14:50:39 Not listening on IPv6 interface.
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 Xinerama is present and active (e.g. multi-head).
 
24/06/2019 14:50:39 Xinerama: number of sub-screens: 1
 
24/06/2019 14:50:39 Xinerama: no blackouts needed (only one sub-screen)
 
24/06/2019 14:50:39
 
24/06/2019 14:50:39 fb read rate: 180 MB/sec
 
24/06/2019 14:50:39 fast read: reset -wait  ms to: 10
 
24/06/2019 14:50:39 fast read: reset -defer ms to: 10
 
24/06/2019 14:50:39 The X server says there are 10 mouse buttons.
 
24/06/2019 14:50:39 screen setup finished.
 
24/06/2019 14:50:39
 
  
The VNC desktop is:      debian:0
+
== C♯のコード ==
PORT=5900
+
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;
  
******************************************************************************
+
//追加
Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?
+
using System.Runtime.InteropServices;
  
The scheme stores pixel data offscreen on the VNC viewer side for faster
+
namespace CSharpToCDLL
retrieval. It should work with any VNC viewer. Try it by running:
+
{
 +
    /// <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);
  
    x11vnc -ncache 10 ...
+
        /// <summary>
 +
        /// 標準のコンストラクタ
 +
        /// </summary>
 +
        public MainWindow()
 +
        {
 +
            InitializeComponent();
 +
        }
  
One can also add -ncache_cr for smooth 'copyrect' window motion.
+
        /// <summary>
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
+
        /// ボタンクリックイベントハンドラ
 +
        /// </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>
 
</syntaxhighlight>
  
VNC Viewerなどで接続してみてください。<br/>
+
=== ビュー ===
デスクトップが表示されたら、成功です。
+
<source lang="xml">
 
+
<Window x:Class="CSharpToCDLL.MainWindow"
 
+
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Viewerを終了して気づいた方もいらっしゃるかもしれませんが、この状態だとViewerを終了するとX11vncも終了してしまいます。<br/>
+
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ココらへんは、オプションで設定します。
+
        Title="MainWindow"
 
+
        Height="77.056"
 
+
        Width="525">
先ずは、終了しないようにします。<br/>
+
    <Grid>
終了しないようにするには、「-forever」オプションを指定します。<br/>
+
        <Grid.RowDefinitions>
<syntaxhighlight lang="bash">x11vnc -display :0 -rfbauth ~/.vnc/passwd -forever</syntaxhighlight>
+
            <RowDefinition Height="5"/>
 
+
            <RowDefinition Height="24"/>
あと…表示されているメッセージに基づいてオプションを設定していきます。
+
            <RowDefinition/>
<syntaxhighlight lang="bash">24/06/2019 15:56:31 X DAMAGE available on display, using it for polling hints.
+
            <RowDefinition Height="5"/>
24/06/2019 15:56:31  To disable this behavior use: '-noxdamage'
+
        </Grid.RowDefinitions>
24/06/2019 15:56:31
+
        <Grid.ColumnDefinitions>
24/06/2019 15:56:31  Most compositing window managers like 'compiz' or 'beryl'
+
            <ColumnDefinition Width="5"/>
24/06/2019 15:56:31  cause X DAMAGE to fail, and so you may not see any screen
+
            <ColumnDefinition/>
24/06/2019 15:56:31  updates via VNC. Either disable 'compiz' (recommended) or
+
            <ColumnDefinition Width="5"/>
24/06/2019 15:56:31  supply the x11vnc '-noxdamage' command line option.</syntaxhighlight>
+
            <ColumnDefinition Width="75"/>
「-noxdamage」を指定したほうが良さそうです。<br/>
+
            <ColumnDefinition Width="5"/>
(正しく理解できていません…)
+
        </Grid.ColumnDefinitions>
<syntaxhighlight lang="bash">x11vnc -display :0 -rfbauth ~/.vnc/passwd -forever -noxdamage</syntaxhighlight>
+
        <Label
 
+
            Grid.Row="1"
<syntaxhighlight lang="bash">24/06/2019 15:56:31 Wireframing: -wireframe mode is in effect for window moves.
+
            Grid.Column="1"
24/06/2019 15:56:31  If this yields undesired behavior (poor response, painting
+
            Content="{Binding Label_Content}"/>
24/06/2019 15:56:31  errors, etc) it may be disabled:
+
        <Button
24/06/2019 15:56:31    - use '-nowf' to disable wireframing completely.
+
            Grid.Row="1"
24/06/2019 15:56:31    - use '-nowcr' to disable the Copy Rectangle after the
+
            Grid.Column="3"
24/06/2019 15:56:31      moved window is released in the new position.
+
            Content="実行"
24/06/2019 15:56:31  Also see the -help entry for tuning parameters.
+
            Click="Button_Click"/>
24/06/2019 15:56:31  You can press 3 Alt_L's (Left "Alt" key) in a row to
+
    </Grid>
24/06/2019 15:56:31  repaint the screen, also see the -fixscreen option for
+
</Window>
24/06/2019 15:56:31  periodic repaints.</syntaxhighlight>
+
</source>
「反応が悪い」「塗りつぶしエラー」などが出るのであれば、「-nowf」を設定した方が良いようです。<br/>
+
=== ビューモデル ===
「-nowcr」は「ウインドウの移動等をしたあとの、長方形のコピーを無効化」って…よくわからないですね…<br/>
+
<source lang="csharp">
まぁ、エラーが出ない限りは設定する必要はなさそうです。<br/>
+
using System;
 
+
using System.Collections.Generic;
<syntaxhighlight lang="bash">24/06/2019 16:03:24 XFIXES available on display, resetting cursor mode
+
using System.Linq;
24/06/2019 16:03:24  to: '-cursor most'.
+
using System.Text;
24/06/2019 16:03:24  to disable this behavior use: '-cursor arrow'
+
using System.Threading.Tasks;
24/06/2019 16:03:24  or '-noxfixes'.
 
24/06/2019 16:03:24 using XFIXES for cursor drawing.
 
24/06/2019 16:03:24 GrabServer control via XTEST.</syntaxhighlight>
 
「XFIXES」を調べてみたけどがよくわからないな…<br/>
 
Wikiによると「いくつかのプロトコルの変更」と書かれている…<br/>
 
ということは、無視したほうが良いのかな?<br/>
 
無効にする場合は「-cursor arrow」か「-noxfixes」を設定するみたい。
 
 
 
<syntaxhighlight lang="bash">24/06/2019 16:03:24 Scroll Detection: -scrollcopyrect mode is in effect to
 
24/06/2019 16:03:24  use RECORD extension to try to detect scrolling windows
 
24/06/2019 16:03:24  (induced by either user keystroke or mouse input).
 
24/06/2019 16:03:24  If this yields undesired behavior (poor response, painting
 
24/06/2019 16:03:24  errors, etc) it may be disabled via: '-noscr'
 
24/06/2019 16:03:24  Also see the -help entry for tuning parameters.
 
24/06/2019 16:03:24  You can press 3 Alt_L's (Left "Alt" key) in a row to
 
24/06/2019 16:03:24  repaint the screen, also see the -fixscreen option for
 
24/06/2019 16:03:24  periodic repaints.</syntaxhighlight>
 
スクロール検出に関する設定???<br/>
 
「反応が悪い」「塗りつぶしエラー」などが出るのであれば、「-noscr」を設定した方が良いようです。<br/>
 
ただ…「定期的な再描画については『-fixscreen』を参照」とも言っているので、そちらをヘルプで参照したほうが良いかな?<br/>
 
 
 
<syntaxhighlight lang="bash">24/06/2019 16:03:24 XKEYBOARD: number of keysyms per keycode 10 is greater
 
24/06/2019 16:03:24  than 4 and 100 keysyms are mapped above 4.
 
24/06/2019 16:03:24  Automatically switching to -xkb mode.
 
24/06/2019 16:03:24  If this makes the key mapping worse you can
 
24/06/2019 16:03:24  disable it with the "-noxkb" option.
 
24/06/2019 16:03:24  Also, remember "-remap DEAD" for accenting characters.</syntaxhighlight>
 
どうやら自動的に「-xkb」モードに変更されているっぽい。<br/>
 
まぁそれはそれで良いと思うのだけど、メッセージが表示されるのは気持ち悪いので「-xkb」を設定してみる。
 
<syntaxhighlight lang="bash">x11vnc -display :0 -rfbauth ~/.vnc/passwd -forever -noxdamage -xkb</syntaxhighlight>
 
 
 
う~ん…色々設定が合って難しいなぁ~。<br/>
 
あと、必要そうなオプションは「-loop」です。<br/>
 
「[https://qtotter.wordpress.com/2013/08/23/%E3%80%90ubuntu%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E5%86%8D%E6%A7%8B%E7%AF%89%E3%80%91no-04-x11vnc%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/ 【ubuntuサーバー再構築】no.04 x11vncを設定してみる – 犬を一匹飼っている]」によると、「こけたらまた起動し直す」ようです。<br/>
 
 
 
まぁ、色々あって最終的には…
 
<syntaxhighlight lang="bash">x11vnc -display :0 -rfbauth ~/.vnc/passwd -forever -noxdamage -xkb -wf -cursor most -fixscreen V=10 -fixscreen C=10 -loop</syntaxhighlight>
 
って感じでしょうか?<br/>
 
もし「キーリピート(キーを押しっぱなしにしたときに連続して入力)」を有効にしたい場合は「-repeat」を設定してください。
 
 
 
 
 
= X11vncの自動起動設定 =
 
「systemd」を使用して、x11vncをDebian起動時に起動するように設定します。<br/>
 
まずは、「/etc/systemd/system」ディレクトリに「x11vnc.service」ファイルを作成します。<br/>
 
以下のコマンドを実行して、ファイルを作成します。
 
<syntaxhighlight lang="bash">sudo nano /etc/systemd/system/x11vnc.service</syntaxhighlight>
 
内容は以下のとおりです。
 
<syntaxhighlight lang="bash">[Unit]
 
Description=x11vnc (Remote access)
 
After=network-online.target
 
 
 
[Service]
 
Type=simple
 
ExecStart=/usr/bin/x11vnc -display :0 -rfbauth /home/[ユーザーID]/.vnc/passwd -forever -noxdamage -xkb -wf -cursor most -fixscreen V=10 -fixscreen C=10 -loop
 
ExecStop=/bin/kill -TERM $MAINPID
 
ExecReload=/bin/kill -HUP $MAINPID
 
KillMode=control-group
 
Restart=on-failure
 
User=[ユーザーID]
 
  
[Install]
+
//追加
WantedBy=graphical.target</syntaxhighlight>
+
using System.ComponentModel;
[ユーザーID](2箇所)を前段でログインしっぱなしにしたユーザーIDに変更してください。
 
  
そしたらサービスを起動してみます。<br/>
+
namespace CSharpToCDLL
以下のコマンドを実行してください。
+
{
<syntaxhighlight lang="bash">sudo systemctl start x11vnc</syntaxhighlight>
+
    class MainWindowViewModel : INotifyPropertyChanged
正常に実行できているか確認します。
+
    {
<syntaxhighlight lang="bash">sudo systemctl status x11vnc</syntaxhighlight>
+
        /// <summary>
以下の様に表示されれば問題ないかと思います。
+
        /// ラベル表示用変数
<syntaxhighlight lang="bash">test@debian:/etc/systemd/system$ sudo systemctl status x11vnc.service
+
        /// </summary>
● x11vnc.service - x11vnc (Remote access)
+
        private String m_Label_Content;
  Loaded: loaded (/etc/systemd/system/x11vnc.service; disabled; vendor preset: enabled)
 
  Active: active (running) since Mon 2019-06-24 17:15:29 JST; 2s ago
 
Main PID: 2761 (x11vnc)
 
    Tasks: 2 (limit: 4915)
 
  CGroup: /system.slice/x11vnc.service
 
          ├─2761 /usr/bin/x11vnc -display :0 -rfbauth /home/test/.vnc/passwd -forever -noxdamage -xkb -wf -cursor most -fixscreen V=10 -fixscreen C=10 -l
 
          └─2762 /usr/bin/x11vnc -display :0 -rfbauth /home/test/.vnc/passwd -forever -noxdamage -xkb -wf -cursor most -fixscreen V=10 -fixscreen C=10 -l
 
  
6月 24 17:15:30 debian x11vnc[2761]: 24/06/2019 17:15:30
+
        /// <summary>
6月 24 17:15:30 debian x11vnc[2761]: The VNC desktop is:      debian:0
+
        /// ラベル表示文字列
6月 24 17:15:30 debian x11vnc[2761]: PORT=5900
+
        /// </summary>
6月 24 17:15:30 debian x11vnc[2761]: ******************************************************************************
+
        public String Label_Content
6月 24 17:15:30 debian x11vnc[2761]: Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?
+
        {
6月 24 17:15:30 debian x11vnc[2761]: The scheme stores pixel data offscreen on the VNC viewer side for faster
+
            set
6月 24 17:15:30 debian x11vnc[2761]: retrieval. It should work with any VNC viewer.  Try it by running:
+
            {
6月 24 17:15:30 debian x11vnc[2761]:    x11vnc -ncache 10 ...
+
                this.m_Label_Content = value;
6月 24 17:15:30 debian x11vnc[2761]: One can also add -ncache_cr for smooth 'copyrect' window motion.
+
                this.OnPropertyChanged("Label_Content");
6月 24 17:15:30 debian x11vnc[2761]: More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching</syntaxhighlight>
+
            }
「-ncache」オプションやってみ?みたいなメッセージが出ていますが…無視します。<br/>
+
            get { return this.m_Label_Content; }
試しに「-ncache 10」とか設定してつないでみてください。<br/>
+
        }
特に問題なければそれでいいですが…RealVNCのVNC Viewerだと、超縦長な画面になります…。
 
  
= 雑感 =
+
        /// <summary>
自動ログインでログインしっぱなしにする必要があるので、何となく「不安」を感じます。<br/>
+
        /// プロパティ変更イベントハンドラ
なんか、色々すればどうにかなるみたいですが…無理矢理感が否めないので、私はここまでとします。<br/>
+
        /// </summary>
 +
        public event PropertyChangedEventHandler PropertyChanged;
  
= 参考サイト =
+
        /// <summary>
[https://qtotter.wordpress.com/2013/08/23/%E3%80%90ubuntu%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E5%86%8D%E6%A7%8B%E7%AF%89%E3%80%91no-04-x11vnc%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/ 【ubuntuサーバー再構築】no.04 x11vncを設定してみる – 犬を一匹飼っている]<br/>
+
        /// プロパティ変更通知
 +
        /// </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:Debian]]
+
[[Category:C♯]]
[[Category:x11vnc]]
+
[[Category:C++]]
 +
[[Category:dll]]

2019年7月26日 (金) 07:46時点における版

久しぶりにやったら、すっかり忘れていたので覚書…

C++のDLLプロジェクト作成

まず、C++のDLLを作成するときの注意点… 作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。
CShapeToCppDll-005.jpg


あと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。
CShapeToCppDll-001.jpg


空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.cpp」「CppDll.h」「CppDll.def」を追加したよ。


そしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。
(DebugとReleaseでそれぞれ設定する必要があるんだよ。)
CShapeToCppDll-002.jpg

DLLのコード

ヘッダーファイル(*.h)

#ifndef DLLAPI
#define DLLAPI extern "C" __declspec(dllimport)
#endif

DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);

コードファイル(*.cpp)

#define DLLAPI

#include "CppDll.h"

DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2)
{
	return p_Number1 + p_Number2;
}

モジュール定義ファイル(*.def)

LIBRARY	CppDll

EXPORTS
	_Sum

C♯のプロジェクト作成

ほとんどそのまま作るんだけど…ソリューションのコンパイル対策をしておくよ。

ビルドイベントの設定

C++のDLLはソリューションフォルダ直下の「Debug」や「Release」フォルダにDLLが格納されてしまうんだ。そうすると、デバッグするときにDLLが見つからないので、ビルドイベントを使ってコピーしてしまうよ。以下のように設定してね。(「Release」コンパイルするまでは「Release」フォルダがないのでコメントアウトしているよ)
CShapeToCppDll-004.jpg

プロジェクトの依存関係の設定

コピーするにもちゃんとリコンパイルされた資源をコピーしないといけないので、プロジェクトの依存関係を設定することで、ビルドの順番を設定するよ。
ソリューションエクスプローラーからC♯のプロジェクトを右クリックして「ビルド依存関係」→「プロジェクト依存関係」を選択してね。
「依存関係」タブの依存先にC++のプロジェクトが表示されているはずだから、チェックを入れてOKボタンをクリックしてね。

C♯のコード

MVVMモデルでサンプルを作ったからビューモデルが入っているけど…DLLを呼ぶには必要ないから無視してね。

モデル

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());
        }
    }
}

ビュー

<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>

ビューモデル

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));
            }
        }
    }
}