2012-04-08 24 views
4

から設定します。アンマネージC DLLのC#バインディングを作成しています。アンマネージC DLLのパブリックフィールドをC#

DLLは、いくつかのデータを返すために5つのフックが用意されています

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

などのフィールドをエクスポート:ちょうど私を与えた私はバインディングコードを生成するInterop Assistantを使用していた今

EXTERN t_libpd_printhook libpd_printhook; 

、デリゲートの定義:

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

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

+0

ああ、それは分かりませんでしたが、私はそれに代理人をどのように割り当てますか? – thalm

+0

うん、私はあなたの答えを今すぐ受け入れました。私の質問に対する正解です。しかし、私が使用しているDLLはオープンソースなので、私はおそらくusrとして提案されているセッターメソッドを追加します。私はこれが参考になることがわかった:http://stackoverflow.com/questions/2167895/howto-implement-callback-interface-from-unmanaged-dll-to-net-app – thalm

+0

興味深い質問と私はセッターがネイティブコードをコンパイルしている場合は適切なソリューションです。 –

答えて

4

LoadLibraryおよびGetProcAddressを使用して、エクスポートされたlibpd_printhook変数へのポインタを取得できます。代理人に割り当てるにはMarshal.WriteIntPtrMarshal.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); 

私は簡潔な例のために私がexcisedエラーチェックを追加したいと思うでしょう。

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

+0

ありがとう、非常に良い例!私は両方の方法を評価します。私はdllのソースを持っているので、私は設定メソッドを書くことができます。 – thalm

3

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

+1

はい、絶対にあなたは真実です – pylover

+1

大丈夫ですので、私はCのセットメソッドを追加する必要があります...ありがとう! – thalm

関連する問題