- ベストアンサー
dllの呼び出しで引数が渡らないらしい
- 50間近になって.NETにチャレンジ。日々?!?の毎日です。ネットに転がっていた「静的にdllを引用する」コードは動きました。が、「動的にdllを引用」するコードをネットからかき集めてくみ上げましたが引数が旨く渡らないのか、思うように動きません。
- 下記の問題が2つ 1)引数に「ref」を付けないと「保護されたメモリ…」のエラーが発生してしまう。 たぶん、このような現象が出ること自体に呼び出し方の問題がある? 2)最終的にファイル名fnがdll側に旨く渡っていないように思える。 Marshal…を使うのかも知れませんが、よくわかりません。
- 素人質問で恐縮ですが、下記のような動的なdllの引用で、静的な引用と同じように動くコードの書き方を教えて下さい。言語はc#です。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
gogo.dllの呼び出し規約を見ると、パラメータにvoid*を利用した呼び出しが多く見られます。 ちょっと試しに作ってみました。getConfigureとsetConfigureくらいしか確認していませんが、呼び出し方法のヒントくらいにはなるかと・・・ [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] static extern IntPtr LoadLibrary(string lpLibFileName); [DllImport("kernel32", SetLastError = true)] static extern int FreeLibrary(IntPtr hModule); [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true)] static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); delegate int d_MPGE_initializeWork(); delegate int d_MPGE_setConfigure(uint mode, uint dwPara1, IntPtr dwPara2); delegate int d_MPGE_getConfigure(uint mode, IntPtr dwPara1); private d_MPGE_initializeWork pfMPGE_initializeWork; private d_MPGE_setConfigure pfMPGE_setConfigure; private d_MPGE_getConfigure pfMPGE_getConfigure; private int SetConfigure(uint mode, uint param1, string param2) { IntPtr pStr = Marshal.StringToHGlobalAnsi(".\\test1.wav"); int nRtn = pfMPGE_setConfigure(mode, param1, pStr); Marshal.FreeHGlobal(pStr); return nRtn; } private int SetConfigure(uint mode, uint param1) { IntPtr pInt = new IntPtr(0); int nRtn = pfMPGE_setConfigure(mode, param1, pInt); return nRtn; } private int GetConfigure(uint mode, ref string param1) { IntPtr pStr = Marshal.AllocHGlobal(256); int nRtn = pfMPGE_getConfigure(mode, pStr); param1 = Marshal.PtrToStringAnsi(pStr); Marshal.FreeHGlobal(pStr); return nRtn; } private int GetConfigure(uint mode, ref int param1) { IntPtr pInt = Marshal.AllocHGlobal(1 * Marshal.SizeOf(typeof(Int32))); int nRtn = pfMPGE_getConfigure(mode, pInt); param1 = Marshal.ReadInt32(pInt); Marshal.FreeHGlobal(pInt); return nRtn; }
その他の回答 (1)
- reset_cat
- ベストアンサー率68% (94/138)
#1の続き・・・ private void button1_Click(object sender, EventArgs e) { IntPtr hModule = LoadLibrary("gogo.dll"); IntPtr pFunc = GetProcAddress(hModule, "MPGE_initializeWork"); pfMPGE_initializeWork = Marshal.GetDelegateForFunctionPointer(pFunc, typeof(d_MPGE_initializeWork)) as d_MPGE_initializeWork; pFunc = GetProcAddress(pModule, "MPGE_setConfigure"); pfMPGE_setConfigure = Marshal.GetDelegateForFunctionPointer(pFunc, typeof(d_MPGE_setConfigure)) as d_MPGE_setConfigure; pFunc = GetProcAddress(pModule, "MPGE_getConfigure"); pfMPGE_getConfigure = Marshal.GetDelegateForFunctionPointer(pFunc, typeof(d_MPGE_getConfigure)) as d_MPGE_getConfigure; int nRtn = pfMPGE_initializeWork(); nRtn = SetConfigure(3, 2); nRtn = SetConfigure(1, 0, ".\\test2.wav"); string strBuf = ""; nRtn = GetConfigure(1, ref strBuf); int nMode = 0; nRtn = GetConfigure(3, ref nMode); nRtn = FreeLibrary(hModule); } てけとーに作ったので、所々変なのはご了承を・・・
お礼
ウォォォォォ!神様、動いた! この3週間、Web見ながら、あんなに苦労したのに、まるで嘘のように動いた! ありがとうございます。 まだ、わからないコードが多いですが、少しずつ変えてカットアンドトライしながら勉強します。 ありがとうございました。