• 締切済み

VB.NET DLL【API関数(コールバック関数)】の呼び出し方法について

目的は下記(3)のAPI関数をVB.NETで呼び出したいのですが、そこにいきつくまでにいろいろと壁にぶちあたっております。 (1)API関数をVB.NETから利用するにあたって どのような手順および調査・学習すればVB.NETからWin32 APIを独力で呼び出せるようになるのでしょうか?ネット上に情報が乏しく、いきずまっております。 (2)API関数の調査方法、またコールバック関数について 下記(a),(b)のようにWin32 API関数を宣言して、あとは呼び出し側の関数で(a),(b)で宣言したAPI関数を記述するだけで基本的には使用できるようになるという大まかなイメージはつかめております。 このあとでAPI関数をMSDNで調べると引数がHWNDやPCTSTRなど見慣れないものが出てきて、次のURL(http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html)を見ると、APIの型とVB.NETの型は違うので型変換をしなければならないとあります。またさらに私が呼び出したい関数はコールバック関数なるものでこれまた?な状態です。 そこでAPIとVB.NETの型変換の調査方法およびコールバック関数の利用方法などを教えていただけないでしょうか? (a)DllImport属性を利用する方法 <System.Runtime.InteropServices.DllImport("DLL名")> _ Function API関数名(仮引数) End Function (b)Declareステートメントを利用する方法 Declare Function API関数名 Lib "DLL名" (仮引数) (3)InstallHinfSection関数(http://msdn2.microsoft.com/en-us/library/aa376957.aspx)について 下記のコードを実行したのですが、実行時エラーにはならないのですが、APIの関数が動作してくれません。どこが悪いのかがまったく見当がつかないのですがどなたかアドバイスいただけると助かります。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click InstallHinfSection(Nothing, Nothing, "DefaultInstall 132 C:\INF_TEST\Original.inf", 0) End Sub   Declare Function InstallHinfSection Lib "setupapi" Alias "InstallHinfSection" (ByVal hwnd As String, ByVal ModuleHandle As String, ByVal CmdLineBuffer As String, ByVal nCmdShow As Integer) As Long APIが難しすぎていろいろとおかしなことを書いているかもしれませんが、どうぞよろしくお願いいたします。

みんなの回答

回答No.1

>コールバック関数 これを直接呼び、実行することはありません。 コールバック関数は用意しておくものです。 仮に ※普通のAPI関数をA関数 ※コールバック用の関数をB関数 とします もしB関数を直接 Sub ボタンクリック()   B関数(引数1,引数2) End Sub などとした場合、すでにこれはコールバック関数として利用していないことになります。 Sub ボタンクリック()   A関数(引数1,B関数のアドレスポインタ) End Sub として、APIのA関数からB関数を実行する場合が、B関数をコールバック関数として利用したことになります。 よって、B関数を実行するロジックが、コード上には存在しないけど、実行されます。 [3355240:「フォルダの参照」ダイアログのタイトル変更] http://okwave.jp/qa3355240.html ここで、.NETでのコールバック実例を挙げました。 フォルダ参照の呼び出しの構造体に、関数ポインタを利用しています。 APIの利用は、MSDNと他のサンプルからのニラメッコから始めると思います。 もしCの知識が多少あれば、アドレス/ポインタの考え方を利用すると、置き換えもそれほど難しくありません。 基本は.NETであれば、ほとんど値渡しのIntegerかIntPtrで事足ります。 VB側で利用している変数のポインタを渡す事になります。 ただそれだと、毎回変数のアドレスを取得しなければなりません。わざわざ変数のアドレスを算出しなくてよい場合もあります。 まずAPI関数の個々の特性は、やはりMSDNやVBに限らずに参考文献を探し、理解することです。 それによって、構造体のまま参照渡しでもよいものもありますし、構造体領域分を確保したポインタを値渡しする場合もあります。 文字列変数をそのまま利用できるものもありますし、、、、、 それと人によって置き換え方は様々です。 [1267832:API,PathIsDirectoryについて] http://okwave.jp/qa1267832.html 最後は結局「慣れ」だと思います。 「InstallHinfSection」についての質問ってことでなければ、上記で以上。 「InstallHinfSection」についての質問ってことであれば、、、すいません、、よくわかりません。 ただ、、、InstallHinfSectionってコールバックとして呼ばれる関数ですよね? 使ったことがないのでよくわからないのですが、、、ググると「rundll32.exe 」がセットで引っかかります。 ※何をしようとしているか ※何を元に作成しているか(参考URL) を載せると、もっと的を射たアドバイスができると思うのですが、、、

20centuryboy
質問者

補足

返信が遅くなり申し訳ありません。ご回答ありがとうございます。 改めてお伺いしたいのですが… (1)コールバック関数は直接呼ぶのではなく、用意しておくものとのことですが、仮に「CALL コールバック関数(仮引数)」と直接呼び出すコーディングをしても使用できないということでしょうか?また、教えていただきましたサンプルのコールバック関数ですが、現在の私のレベルでは理解することができませんでした。もしよろしければ簡単なコールバック関数の呼び出しかたをご教授いただけないでしょうか? (2)APIについて やはり文献、参考URL探しからの調査で慣れですか… 1050YENさんのお勧めのURLや文献等ありましたら教えていただけないでしょうか? (3)目的 INFファイルを使ってインストールを行いたいのですが、方法はINFファイルを右クリックでインストールか、RUNDLL32 InstallHinfSectionでコマンドプロンプトを実行するかの2通りしかいろいろと調査した結果見つけられませんでした。コマンドプロンプトのような外部アプリに頼らずに、InstallHinfSectionのAPI関数を直接コーディングすることで実現(APIの勉強も兼ねて)したいのですが、参考URL(http://www.trickpalace.net/windows/installer/)を見て作成しても動作せずに質問させて頂きました。海外サイトでも同様の試みを行った方がいたのですが、結局あきらめていらっしゃいました。

関連するQ&A

  • API関数(DLL)の呼び出しにおいて、DLLの格納場所は?

    お世話になります。 VB.NETでAPI関数を呼び出す場合にまず、API関数を格納しているDLLを宣言しなけれならないと下記URLにあります。 (http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html) (a)DllImport属性を利用する方法 <System.Runtime.InteropServices.DllImport("DLL名")> _ Function API関数名(仮引数) End Function (b)Declareステートメントを利用する方法 Declare Function API関数名 Lib "DLL名" (仮引数) そこで、質問なのですが、(a)、(b)どちらの方法で実現する場合においても、DLLの格納場所はC:\Windows\System32でないといけないのでしょうか?(実際にコーディングしてもSystem32フォルダにないとエラーになってしまいます。) 任意のフォルダにDLLを格納し、そこを参照できるようにできるのでしょうか? また、一般常識としてDLLはSystem32フォルダに格納しておかないといけないものなのでしょうか? 以上、よろしくお願いいたします。

  • VB(6.0)で作成したDLLをVB(.Net)で呼び出す方法

    VB(6.0)で作成したDLLをVB(.Net)で呼び出すのに Public Declare Function 関数名 Lib "~.dllのパス"               (ByVal ・・・) As 型 このように呼び出してみているのですが 上手くいきません。整数データの変更も しました。 このDLLを呼び出せないと次に進めないので 本当に困っています。 よろしくお願いします。

  • VB.NET デリゲートへのコールバック関数の設定

    VB.NET デリゲートへのコールバック関数の設定 VB.NETとネイティブC/C++ DLL間でのコールバックについての質問です。 ネイティブDLLからVOID*で得られるコールバック関数をVB.NETのデリゲートに 登録するには、どのようにコーディングすればよいのでしょうか。 ---------- VB.NETソース ---------- Public Delegate Sub CALLBACK_00(ByVal Arg1 As Integer, ByVal Arg2 As Integer) Declare Function FuncPtrGet Lib "test.dll" () As CALLBACK_00 Dim Func As new CALLBACK_00(FuncPtrGet()); 2行目は、実際にはVOID*が帰るDLL関数です。 3行目がコンパイルで通りません。AddressOfで関数を指定するようにメッセージが出ます。

  • EnumWindowsのコールバック関数に文字列を

    VBAでのWindows API関数EnumWindowsの定義は下記になっています。 Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long そこで、コールバック関数(lpEnumFunc)へのパラメータ(lParam)に文字列を指定したくて定義を下記のように変更しましたが旨く行きません。(定義をこのように変更することが許されているかも分っていませんが)   変更前:ByVal lParam As Long   変更後:ByRef lParam As String EnumWindowsのコールバック関数へのパラメータに文字列を指定する方法があれば教えて頂きたくよろしくお願いします。

  • C++製DLLにてVB.NET関数を引数付きでコールバックしたい。

    C++製DLLにてVB.NET関数を引数付きでコールバックしたい。 以下のようなソリューションがあります。 ソリューションには、VB.NETによるプロジェクトapp、C++によるプロジェクトdllがあり、 名前のとおり、appはWindowsフォームアプリケーション、dllはクラスライブラリです。 *** VisualStudio.NET 2003 ソリューション *** === VB.NETプロジェクト:app.exe === --- Module1.vb --- Module Module1 Delegate Function _t() As Int32 <System.Runtime.InteropServices.DllImport("dll.dll")> Public Function dllfunc(ByVal lpFunc As _t) As Int32 End Function End Module --- Form1.vb --- Public Class Form1 Inherits Form Private button1 As Button Public Sub New() button1 = New Button button1.Parent = Me : button1.Text = "button1" AddHandler button1.Click, AddressOf MyClass.GetEvent End Sub Private Sub GetEvent(ByVal sender As Object, ByVal e As EventArgs) dllfunc(AddressOf func1) End Sub Public Function func1() As Int32 MsgBox("func1@vb.net") Return 123 End Function End Class === C++ライブラリプロジェクト:dll.dll === --- dll.def --- LIBRARY dll EXPORTS dllfunc --- dll.h --- #ifdef DLL_EXPORTS #define DLL_API __declspec(dllexport) #else #define DLL_API __declspec(dllimport) #endif DLL_API void dllfunc(int* vbfunc(void)); -- dll.cpp --- #include "stdafx.h" #include "dll.h" #include "stdio.h" #include "windows.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return true; } DLL_API void dllfunc(int* vbfunc(void)) { char str[16]; sprintf(str,"vbfunc() = %d",vbfunc()); MessageBoxA(NULL,str,"dll",MB_OK); } --- stdafx.cpp, stdafx.h --- (省略) *** ソリューション ここまで *** [ 動作 ] appを実行すると、Form1にbutton1が生成される。 button1をクリックするとGetEventが呼ばれ、func1のアドレスを引数としたdllfunc()を呼びます。 dll側のdllfunc()から、app側のfunc1()を呼び、戻り値の123を表示します。 [ 質問 ] dllfunc()から引数付きでfunc1()を呼びたいが、記述の方法が分かりません。 ご教示お願い致します。

  • VBからCで作成されたDLLへの引数の渡し方

    VBからCで作成されたAPI関数への引数の渡し方がわかりません。 C側の引数のデータ型はchar型でポインタ渡しではありません。 ------------------------------------------------ C側 int KANSU(char Mode) VB側 Public Declare Function KANSU Lib "USERAPI.dll" ( ByVal CHAR As Byte) As Long ------------------------------------------------ C側がポインタ渡しの場合は、VB側はSTRING型で別に悩むことはなかったのですが、文字列渡しの場合は、VB側はBYTE型で渡す必要があり、その方法がわかりません。 どなたか、分かる方よろしくお願いします。 ちなみに、VB6.0です。

  • Cで作成したDLL関数をVBから呼ぶ

    以前にあった「Cで作成したDLL関数をVBから呼び 引数渡し方法」を試したのですがVB側でデータが受け取れません。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=711327 C側での値設定がわるいのでしょうか? VB側 Public Declare Function testAP Lib "C:\bin\test.dll" (ByVal lpKeyData As String) As Long --------------------------------------------------------------------------- Dim lngRc As Long Dim keydata As String * 128 keydata = String$(128, Chr(0) & Chr(0)) lngRc = testAP(keydata) VC側 __declspec(dllexport) long __stdcall testAP(char *lpdata){ →C側でlpdataに値を設定する lpdata="ABCDEF"; }

  • vc++のAPI(dll)の引数をVBAでうけとる

    Excelで開発しなければならない事情があり、 vc++のAPIが持っている関数を ExcelVBAでコールしておりますが、エラー1041でExcelが強制終了してしまいます。 VBAからVisual C++にchar*型で渡し、ByRef String型でVBAにて受け取ります。 VCの関数の第四引数「char* 型/attribute_value」をVBAの「String 型/sValue」で受け取る際にエラーになっているようです。 VBAでcharに相当する変数型がないためと思われますが、何かよいアイデアがありましたらご教授願います。 --VC-- XDW_GetDocumentAttributeByName(h, attribute_name, &attribute_type, attribute_value, size, NULL); --VBA-- <宣言部> Public Declare Function XDW_GetDocumentAttributeByName Lib "C:\Users\○○○\Desktop\dwsdk710jpn\XDWAPI\DLL\xdwapi.dll" (ByVal lnghandle As Long, ByVal sName As String, ByRef lngType As Long, ByRef sValue As String, ByVal lngSize As Long, ByVal reserved As String) As Long <呼び出し部> Dim lngHandle As Long Dim sName as String Dim lngType As Long Dim sValue As String Dim lngSize as Long Dim tmpSize as Long lngSize = 0 sName = "keiyaku" tmpSize = XDW_GetDocumentAttributeByName(lngHandle, sName, sType, sValue, lngSize, vbNullString) XDW_GetDocumentAttributeByName lngHandle, sName, sType, vbNullString, tmpSize, vbNullString degug.print sValue

  • VB6.0のString関数に代わるVB2008のそれは?

    2009年1月27日にVB 2008Expressをダウンロードしたばかりの初学者です。 ですから、色々とわからないことだらけです。 で、今回は VB6.0のString関数に代わるVB2008のそれ。 ? String(12, "*") ************ Function Strings(ByVal C As Char, ByVal L As Integer) As String   Return Space(L).Replace(" ", C) End Function 少しは探しましたが、適当なのがなくてStrings関数を作成してしまいました。 2週間程度の初学者。 しかも、文字列関連のヘルプは昨日に初めて紐解いたばかり。 ですから、「適当なのがない」との判断はかなり怪しいものです。 そこで、「VB6.0のString関数に代わるVB2008のそれは、これですよ!」という回答をお願いします。

  • API関数 GetPixel

    質問ですが、Visual Basicで Option Explicit Private Declare Function Getpixel Lib "gdi32" (_ ByVal hdc As Long, _ ByVal x As Long, _ ByVal y As Long, _ ) As Long というソース部分があるのですが、これをVC++で書き直すとしたらどのようになるのでしょうか。また、VC++のAPI関数にはGetPixelはないのでしょうか。なにとぞよろしくお願いいたします。

専門家に質問してみよう