Symfoware

Symfowareについての考察blog

C#からwin32なdllを呼び出し、関数を実行する

VB6時代のdllをC#から呼び出して使う方法をメモしておきます。


呼び出すdll



C#から呼び出すdllは、PCView by DLLをお借りしました。
http://www.vector.co.jp/soft/dl/win95/prog/se234999.html

CPUの情報を取得するdllのようです。




サンプル



C#からdllを呼び出すには、System.Runtime.InteropServices名前空間にある
DllImportを使用します。

ざっくりなサンプルは以下のとおり。


  1. using System;
  2. using System.Text;
  3. using System.Runtime.InteropServices;
  4. public class Sample {
  5.     
  6.     [DllImport("PCView.DLL")]
  7.     public static extern int CpuIDsupport();
  8.     
  9.     [DllImport("PCView.DLL")]
  10.     public static extern int VenderID(StringBuilder buffer, int bufsiz);
  11.     
  12.     [DllImport("PCView.DLL")]
  13.     public static extern int BrandString(StringBuilder buffer, int bufsiz);
  14.     
  15.     public static void Main(string[] args) {
  16.         Console.WriteLine(CpuIDsupport());
  17.         
  18.         StringBuilder sb = new StringBuilder(64);
  19.         int ret = VenderID(sb, 64);
  20.         Console.WriteLine(ret);
  21.         Console.WriteLine(sb + "<==END");
  22.         
  23.         ret = BrandString(sb, 64);
  24.         Console.WriteLine(ret);
  25.         Console.WriteLine(sb + "<==END");
  26.     }
  27. }




ちなみに、添付されていたVB6のサンプルコードの宣言は以下のとおり。


  1. Private Declare Function CpuIDsupport Lib "PCView.DLL" () As Long
  2. Private Declare Function VenderID Lib "PCView.DLL" (ByVal buffer As String, ByVal bufsiz As Long) As Long
  3. Private Declare Function BrandString Lib "PCView.DLL" (ByVal buffer As String, ByVal bufsiz As Long) As Long




こちらを参考に、C#へ移植しました。
Win32 APIやDLL関数を呼び出すには?


ビルドして実行すると、こんなエラーが表示されます。

ハンドルされていない例外: System.BadImageFormatException: 間違ったフォーマットのプログラムを読み込もうとしました。 (HRESULT からの例外: 0x8007000B)
場所 Sample.CpuIDsupport()
場所 Sample.Main(String[] args)




間違ったフォーマットのプログラムを読み込もうとしました。
http://d.hatena.ne.jp/none53/20100707/1278470575

こちらがとても参考になりました。

ビルドと実行は、Windows 2008 R2で行ったため、32bitでビルドするよう
コンパイラに指定しないといけないようです。

コンパイルは、特にツールを使用せず、バッチファイルで実行しています。
C# バッチファイルでソースをコンパイルする



こんなバッチファイルで実行していたのを、

@echo off
set csc=C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe /nologo

%csc% sample.cs




こんな感じで、プラットフォーム指定のオプションを追加しました。

@echo off
set csc=C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe /nologo /platform:x86

%csc% sample.cs




実行すると警告が表示されます。


warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Data.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Data.OracleClient.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.EnterpriseServices.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Transactions.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'System.Web.dll' は異なるプロセッサを対象にしています。
warning CS1607: アセンブリの生成 -- 参照アセンブリ 'mscorlib.dll' は異なるプロセッサを対象にしています。




64じゃない方を指定すれば、警告は表示されなくなりました。


@echo off
set csc=C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /nologo /platform:x86

%csc% sample.cs




実行してみると、ちゃんとdllから値が取得で射ている模様です。

1
4
GenuineIntel<==END
-2147483638
QEMU Virtual CPU version 1.0<==END





【参考URL】

PCView by DLL(CPUID)
CPUID命令を使用し情報収集を行うDLL CPUの情報を収集、表示することが可能
http://www.vector.co.jp/soft/dl/win95/prog/se234999.html

Win32 APIやDLL関数を呼び出すには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html

間違ったフォーマットのプログラムを読み込もうとしました。
http://d.hatena.ne.jp/none53/20100707/1278470575

/platform (C# コンパイラ オプション)
http://msdn.microsoft.com/ja-jp/library/vstudio/zekwfyz4.aspx

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2012/12/24(月) 18:44:03|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<xUnitを使用したC#のテストプログラム作成法 | ホーム | C# 固定長ファイルの読み込み>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1060-5a1d200f
この記事にトラックバックする(FC2ブログユーザー)