プログラム言語 外部プログラム連携

概要

必要な機能が大きく、開発に要する時間が短い昨今、
プログラムの全てを自分で開発するのは効率が悪い。
他人が作ったプログラムをソースでなくDLLのまま利用する為の方法。
他言語で開発されたプログラムであってもそれは可能。

参考

Windowsはなぜ動くのか
Windowsの仕組み(.NET Frameworkとは?)
Windowsプログラミング

マーシャリング

異なるシステムへデータを渡す場合に渡し先で有効な型へ変換すること。
マネージ環境のプログラムから、アンマネージ環境で動作するプログラムを呼び出す際にマーシャリングが必要になる。

マーシャラー

マーシャリングを行うプログラム。

マネージ環境

CLR(CommonLanguageRuntime)によって管理された環境。
ガーベッジコレクション、セキュリティ機能等の.NetFrameworkの機能を提供する実行エンジン。
ガーベッジコレクションの動作を含むメモリ管理、配列・文字列の長さ管理が自動で行われる。

アンマネージ環境

上記以外の環境。
Win32API、COMオブジェクト、C/C++等、多言語で作られたプログラム等。
バッファがオーバーフローしない様、ガーベッジコレクションの動作に該当する使い終わったメモリの破棄等の処理は自動では行われない。

COM相互運用

マーシャリングを行った上で.NetFramework←→WindowsAPIでデータをやり取りを行う事。

ウィンドウハンドル

WindowsAPIにおいて操作対象毎に割り振られる管理番号
操作対象へのポインタ

実例

DLL(API)

APIとは?
Windowsプログラミング/API」参照

using System.Runtime.InteropServices;

class MyWin32
{
  [DllImport("USER32.DLL", EntryPoint = "MessageBoxA")]
  public static extern int myMessageBox(
    int hWnd,
    String lpText,
    String lpCaption,
    uint uType);
  
  ※USER32.DLLにおけるMessageBoxAをmyMessageBoxとして宣言
  
  public const int MB_OK = 0x00000000;
  public const int MB_OKCANCEL = 0x00000001;
  public const int MB_ABORTRETRYIGNORE = 0x00000002;
  public const int MB_YESNOCANCEL = 0x00000003;
  public const int MB_YESNO = 0x00000004;
  public const int MB_RETRYCANCEL = 0x00000005;

}

public partial class MyForm : Form
{
  private void MyForm_Load(object sender, EventArgs e)
  {

    MyWin32.myMessageBox(
      hWnd: 0,
      lpText: "メッセージ",
      lpCaption: "キャプション",
      uType: MyWin32.MB_YESNO);
  }
}

DLL(ActiveX)

ActiveXとは?
Windowsプログラミング/API」参照

Dim myObj As Object
myObje = CreateObject("~")
Call myObje.メソッド(~)
myObje.プロパティ = ~
DLL(COM)

COMとは?
Windowsプログラミング/COM」参照

「参照設定」によるDLLのパス設定が必要
COMコンポーネントでないDLLは参照設定できない。
DLLのCOM登録は「.NETで作成したDLLをVB6から呼び出す方法」参照

Dim myObj As New ~
Call myObje.メソッド(~)
myObje.プロパティ = ~

EXE

非同期で起動。※呼び出し元PGは実行されたまま。

' メモ帳を起動する
Call Shell("Notepad", vbNormalFocus)

' タスクIDを取得(≠Windowsハンドル)
Dim RetVal As Variant
RetVal = Shell("notepad", vbNormalFocus)
' Windowをアクティブに(≠最小化解除)
Call AppActivate(RetVal)

' ファイルを指定してメモ帳を起動する
Call Shell("Notepad C:\test.txt", vbNormalFocus)

' 引数がスペースを含む場合
Call Shell("""~.exe"" ""2015/05/08 10:00:00""", vbNormalFocus)

vbHide(0)
フォーカスを持ち、非表示
vbNormalFocus(1)
フォーカスを持ち、元のサイズと位置に復元
vbMinimizedFocus(2)
フォーカスを持ち、最小化表示
vbMaximizedFocus(3)
フォーカスを持ち、最大化表示
vbNormalNoFocus(4)
フォーカスを持たず、最後にウィンドウを閉じたときのサイズと位置に復元
※現在アクティブなウィンドウは、アクティブのまま
vbMinimizedNoFocus(6)
フォーカスを持たず、最小化表示
※現在アクティブなウィンドウは、アクティブのまま

プロセスの終了を検知する

using System.Diagnostics;

static void Main()
{
  // プログラムを起動しプロセスのインスタンスを取得
  Process hProcess = Process.Start(
    fileName: @"C:\Test.exe",
    arguments: @"prm1 prm2 prm3");
  
  // ↑プロセスが終了した時にExitedイベントを発生させる
  hProcess.EnableRaisingEvents = true;
  
  // Exitedイベントのハンドラを追加する
  hProcess.Exited += new System.EventHandler(Test_Exited);
  
  // 監視の為にアプリケーションを起動させておく必要あり。
  // タスクバーには表示されないがプロセスは起動する
  Application.Run();
}

private static void Test_Exited(object sender, System.EventArgs e)
{
  プロセス終了時、ここが呼ばれる
}