4

アンマネージ C dll の C# バインディングを作成しています。

dll は、複数のデータを返す 5 つのフックを提供します。

typedef void (*t_libpd_printhook)(const char *recv);

次のようなフィールドをエクスポートします。

 EXTERN t_libpd_printhook libpd_printhook;

今、私はInterop Assistantを使用してバインド コードを生成していました。これにより、デリゲートの定義が得られました。

public delegate void t_libpd_printhook([In] [MarshalAs(UnmanagedType.LPStr)] string recv);

では、DLL で t_libpd_printhook フィールドを設定するために使用できる魔法の Interop 関数呼び出しはありますか?

4

2 に答える 2

4

LoadLibraryおよびを使用GetProcAddressして、エクスポートされたlibpd_printhook変数へのポインターを取得できます。Marshal.WriteIntPtrその後、とを使用Marshal.GetFunctionPointerForDelegateしてデリゲートに割り当てることができます。

[DllImport("kernel32", SetLastError=true, CharSet=CharSet.Unicode)]
static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, 
    SetLastError=true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);

.....

IntPtr lib = LoadLibrary(@"mydll.dll");
IntPtr plibpd_printhook = GetProcAddress(lib, "libpd_printhook");
Marshal.WriteIntPtr(plibpd_printhook, 
    Marshal.GetFunctionPointerForDelegate(mydelegate));
FreeLibrary(lib);

簡潔な例のために、私が削除したエラーチェックを追加することをお勧めします。

これで、アンマネージライブラリを制御している場合でも、この関数ポインターへの書き込みをカプセル化する関数を追加することをお勧めします。それは私にとってより良いインターフェースのように感じます。

于 2012-04-08T21:44:24.653 に答える
3

PInvoke は、エクスポートされた変数をサポートしていません。デリゲートを取得してフィールドにコピーするアンマネージ関数を作成する必要があります。

于 2012-04-08T21:14:57.687 に答える