• 締切済み

読み込むdllが名前違いでたくさんある場合について

同じ引数、戻り値のdllが名前違いで100個あります。 これらをテストするツールを作成しています。 [DllImport("user32.dll")] のdllの部分を可変にすることは可能なのでしょうか?

みんなの回答

回答No.1

記法と内容の都合から, ・C# 2.0以上 ・.NET Framework 2.0以上または.NET Compact Framework 2.0以上 を前提にします。 まず,属性の引数を実行時に変更する事はできないです。 そのため,DllImportAttributeでなんとかする,という方向性で解決する事は出来ません。 ただ,幸い引数と戻り値が同じ (呼び出し規約も同じ?) なので,Win32 APIとの組み合わせで処理できます。 1. LoadLibrary API,GetProcAddress API,FreeLibrary APIをDllImport属性付きで宣言する。 MSDN: LoadLibrary Function (Windows) http://msdn.microsoft.com/en-us/library/ms684175.aspx MSDN: GetProcAddress Function (Windows) http://msdn.microsoft.com/en-us/library/ms683212.aspx MSDN: FreeLibrary Function (Windows) http://msdn.microsoft.com/en-us/library/ms683152.aspx 2. メソッドの型のデリゲートを用意する 3. LoadLibraryでDLLを読み込む 4. GetProcAddressで対象となる関数へのポインタを取得する 5. Marshal.GetDelegateForFunctionPointerで関数ポインタをデリゲートに変換する MSDN: Marshal.GetDelegateForFunctionPointer メソッド (System.Runtime.InteropServices) http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.marshal.getdelegateforfunctionpointer.aspx 6. デリゲートを呼び出す 7. FreeLibraryでDLLを解放する

taku_pon
質問者

お礼

それぞれの項目で出てくる単語が未知のものすぎて 何を書いたらいいのかさっぱりわかりません。 調べたら教えて頂いた内容が出てくるので できそうな気配はします。 勉強してみます。

taku_pon
質問者

補足

ありがとうございます。 開発環境を書き忘れていました。 呼び元はC#2008で呼ばれるのはC(VC6.0でコンパイル)の プログラムです。 

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PythonでDLLからの戻り値で文字列の場合を正しく表示させたい

    VisualStudio2005でDLLを作成して、Python2.6のctypesモジュールを使って、PythonからC++のルーチンを呼び出す際に、文字列を引数として、文字列を戻り値として使えるようにC++を記述したいのですがどうすればよいのでしょうか? 関数呼び出しは __stdcallです。 __declspec(dllexport) unsigned char* __stdcall Test(const char *s, int n); とした場合、Pythonで戻り値を見るとint型の数値でした。 from ctypes import * lib = windll.LoadLibrary("test.dll") s = lib.Test("abcdefghijk", 3) print s

  • DLLの違いについて

    MFC AppWizard(dll)で作成したDLLとWin32 Dynamic-Link Libraryで作成したDLLの違いは何でしょうか?客先に「MFCで作ってないんですか?」と聞かれて何が違うのかなと思いまして。不慣れなものですみません。

  • C#からC++のDLLを使いたい時

    C#からC++(unmanaged)のDLLを使いたい時、 DLLをどのように参照すればよいのでしょうか。 [DllImport("名前.dll")] extern static double 関数名(); という指定は分かるのですが、 それだけじゃもちろん、 「DLL (名前.dll) を読み込めません。」 ってなりますよね・・・。

  • dllの呼び出しで引数が渡らないらしい

    dllの呼び出しで引数が渡らないらしい 50間近になって.NETにチャレンジ。日々?!?の毎日です。 ネットに転がっていた「静的にdllを引用する」コードは動きました。が、「動的にdllを引用」するコードをネットからかき集めてくみ上げましたが引数が旨く渡らないのか、思うように動きません。当該dllはgogo.dllで有名だと思います。 正直、ManagedとUnmanagedのメモリ管理とか、呼び出しの引数の渡し方も理解していません。見よう見まね状態ですが、どうしても当該dllを使いたいので掲載してしまいました。(^_^; 下記の問題が2つ 1)引数に「ref」を付けないと「保護されたメモリ…」のエラーが発生してしまう。  たぶん、このような現象が出ること自体に呼び出し方の問題がある? 2)最終的にファイル名fnがdll側に旨く渡っていないように思える。  Marshal…を使うのかも知れませんが、よくわかりません。 素人質問で恐縮ですが、下記のような動的なdllの引用で、静的な引用と同じように動くコードの書き方を教えて下さい。言語はc#です。 下記がコードですが、文字数削るためかなり行を削っています。初期化とかはちゃんとコーディングしています。 [静的にdll引用=>正常終了] [DllImport("gogo.dll", EntryPoint = "MPGE_setConfigure")] static extern int MPGE_setConfigureStrings(int mode, int dwPara1, string dwPara2); (中略) string fn = "D:\\test.wav"; i = MPGE_setConfigureStrings(1, 0, fn); =>この後、test.wavに対しての処理で正常終了が返る(^_^) [動的にdllを引用=>ダメ] [DllImport("kernel32")] static extern int LoadLibrary(string lpLibFileName); [DllImport("kernel32")] static extern IntPtr GetProcAddress(int hModule, string lpProcName); [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true, CharSet = CharSet.Ansi)] delegate int d_MPGE_setConfigure(ulong mode, ref ulong dwPara1, string dwPara2); [MarshalAs(UnmanagedType.FunctionPtr)] static d_MPGE_setConfigure e_MPGE_setConfigure; (中略) IntPtr p_MPGE_setConfigure = GetProcAddress(dllHandle, "MPGE_setConfigure"); e_MPGE_setConfigure = (d_MPGE_setConfigure)Marshal.GetDelegateForFunctionPointer(p_MPGE_setConfigure, typeof(d_MPGE_setConfigure)); string fn = "D:\\test.wav"; ulong p1 = 0; i = e_MPGE_setConfigure(1, ref p1, fn); =>この後、dllからtest.wavが読み込めない旨のメッセージが吐かれる(T.T) 以上です。

  • 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フォルダに格納しておかないといけないものなのでしょうか? 以上、よろしくお願いいたします。

  • VBAでDLL呼び出し

    VBAに関する使用方法をお教えください。 例えばsheet1のA1の数値をVBC++で作成したDLLファイル内にある関数に引数として渡したいのですが、どうすればよいでしょうか? (どう記述すればよいのでしょうか) 初心者につき、分かりやすく説明をして頂ければ幸いです。 VBC++で作成したDLLファイル名 testdll.dll testdll.dll内で定義してある関数名はtest_sendです 以上、宜しくお願い致します。

  • VS2010C#からのDLL使用について

    VS2010 C#からVC6で作成したDLLへint配列を引数として渡したい。 VC++6で作成されたDLLがあります。 ここで定義されている int test(char*fname,int* x,int* y); ファイルのフルパスを渡すと 返り値が関数の成否のコードを返す。 処理内で x,y にファイルから読み込んだ値が それぞれ上限100個としてセットして返す といったような関数を C#から呼び出したいのですが 1 [DllImport("dll名", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern int test(IntPtr fname, ref int* x,ref int* y); 2 [DllImport("dll名", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern int test(IntPtr fname, ref IntPtr x,ref IntPtr y); と2種類の呼び出し方法をこころみました。 ファイルのフルパスは IntPtr fnamePtr = Marshal.StringToHGlobalAnsi(string型ファイルフルパス); としております。 1の場合は int[] resX = new int[100]; int[] resY = new int[100]; fixed(int* x= resX) fixed(int* x= resY) として呼び出そうとすると : エラー CS1657: '固定変数' であるため、'x' を ref または out 引数として渡せません となり失敗してしまいます。 2 で試みた場合 int size = sizeof(int)*100; IntPtr x = Marshal.AllocHGlobal(size); IntPtr y = Marshal.AllocHGlobal(size); と引き渡したところ ビルドは通りますが 実行時に System.AccessViolationException' のハンドルされていない例外が 発生しました。 追加情報: 保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。 となってしまいます。 どのようにすれば思惑通りの結果を得られますでしょうか。

  • DLLの作り方

    DLLでは、ポインタのアドレス渡しのように、可変長サイズのVectorコンテナを引数にすることは可能ですか? DLLのソースコ-ド extern "C" __declspec(dllexport) void __stdcall matinv(vector<vector<complex<double> > >,vector<vector<complex<double> > >&); void __stdcall matinv(vector<vector<complex<double> > > a,vector<vector<complex<double> > > &a_inv) {   コード  } 呼び出し側の関数宣言 #include <vector> #include <math.h> #pragma hdrstop #include <complex.h> using namespace std; extern "C" __declspec(dllimport) void __stdcall matinv(vector<vector<complex<double> > > a,vector<vector<complex<double> > > &a_inv); よろしく御願いいたします。

  • C#での自作DLL(C言語)の並列化

    C言語で自作したDLLをC#で使いたいと考えております。 このDLLの計算量は多くて、値を返すまでに時間がかかります。 そのためにC#のフォームが応答なしになってしまうので並列化したいと思ったのですがうまくいきませんでした。 このDLLは ・int型の戻り値 ・6個の引数 ・上の引数のうち、1つはoutキーワード(ポインタ渡し) です。 どのようにすれば、うまく並列化できるでしょうか。 ご教授お願いいたします。

  • 自作DLLの引数について、ポインタ渡しが??

    VS2005 VC++環境でMFCスマートデバイスDLLを作成しています(アプリ側もVS2005 VC++)。 テスト用のアプリからDLL内の文字列を引数とする関数を呼び出すと、 呼ばれた関数に正しく文字列が渡りません。 以下の場合、func1のw1はデバッガで正しく見れません。 でもw2にtcscpyは成功しw2には正しく値がセットされます。 このときにw1のアドレスがなぜか変更されます。 以下の例では引数が1つですが、2つ以上引数がある時には その他の引数のアドレスもとびます。 func2のl1は正常に見れます。 func3のl1は正常に見れません。 ポインタ渡しするときに異常になるのですが、 原因がさっぱりわかりません。 同じことをWindowsXP用のプロジェクトを作り、 XPで確認するとどれも正常に見れます。 どなたかアドバイスをお願いします。 ----------------------------------------DLL側---------------------------------------- extern "C" __declspec(dllexport) void func1(WCHAR * w1) { WCHAR w2[16] ; _tcscpy(w2,w1); return; } extern "C" __declspec(dllexport) void func2(long l1) { long l2 ; l2 = l1 ; return; } extern "C" __declspec(dllexport) void func3(long *l1) { long l2 ; l2 = *l1 ; return; } ----------------------------------------アプリ側---------------------------------------- extern "C" __declspec(dllimport) void func1(WCHAR *); extern "C" __declspec(dllimport) void func2(long ); extern "C" __declspec(dllimport) void func3(long *); ・・・・中略・・・・ WCHAR a[16] ; _tcscpy(a,_T("ABC")); func1(a); func2(123); long l3 = 123 ; func3(&l3);