2012-03-02 47 views
0

私はPに/以下のCメソッド呼び出し、必要があるからDLL持っているとの方法でクラッシュが発生します。P /呼び出しは、構造体と、コールバックパラメータ

P /呼び出しアシスタントを使用
int DAOpen(HANDLE *hOpen, UNIT *flags, void *callback, void *userData) 

を、私が来ています次のシグネチャを持つアップ:

[DllImportAttribute("<libName>", EntryPoint="DAOpen")] 
    static extern int DAOpen( 
    out IntPtr hOpen, 
    ref uint flags, 
    IntPtr callback, 
    IntPtr userData); 

コールバックパラメータ次のCシグネチャに対応しなければならないがあります

void CallBack( 
    int event, 
    int socket, 
    struct _iComStructure *plcom, 
    void *eventData, 
    void *myData) 

さて、私は次のように呼び出しをやってる

delegate void CallBack( 
    int @event, 
    int socket, 
    IntPtr plcom, 
    IntPtr eventData, 
    IntPtr myData); 

に換算さ:

void MyCallBack(int @event, int socket, IntPtr plcom, IntPtr eventData, IntPtr myData) 
{ 
    // does nothing for now 
} 

IntPtr hOpen; 
uint flags = 0; 
CallBack callBack = MyCallBack; 
StringBuilder userData = new StringBuilder(userData.ToString()); 


int rc = DAOpen(
out hOpen,  
ref flags, 
Marshal.GetFunctionPointerForDelegate(callBack), Marshal.StringToHGlobalAnsi(userData.ToString())); 

私はこのコードを抱えている問題はそれのいずれかクラッシュしたり、私が取得するということですDAOpenを呼び出すとFatalExecutionEngineErrorがスローされます。私はそれがマーシャルエラーでなければならないことを知っていますが、私はそれを理解することはできません...

あなたの助けてくれてありがとう!

ようが示唆された

UPDATE、私は次のようにコールバックを固定しようとした:

GCHandle callbackHandle = GCHandle.Alloc(callBack, GCHandleType.Pinned); 

私はこのメッセージにArgumentExceptionを取得:

Object contains non-primitive or non-blittable data

GCHandleTypeを指定しないとうまくいくようです(つまり、私は漢字を取得しますdle)、当然元の問題が残っています。

私はデリゲートをピンできない理由はありますか?

ありがとうございました!

答えて

2

代理人がガベージコレクションされていないことを確認するための対策はありますか?

呼び出し中にgen 0の収集が開始された可能性があります。 呼び出し元関数 にローカル変数を作成するか、手動でGCハンドルにデリゲートを固定してみてください。

更新:

はまた、ネイティブAPIのコールバックの呼び出し規約 を見てください。それはstdcallですか? は、stdcall引数を期待するネイティブ関数へのポインタを返すので、GetFunctionPointerForDelegateは使用できません。

この場合、intptrではなく、デリゲート型を使用し、ネイティブ呼び出し規約を指定するデリゲート定義に "UnmanagedFunctionPointerAttribute"を配置します。

+0

デリゲートを格納するためのクラス変数を作成しましたが、まだ問題があります。 – XenoAce

+0

@XenoAceネイティブコードに提供するコールバックは、ピンボークコール以外のネイティブコードでも存続する場合は固定する必要があります。 – JaredPar

+0

@Scott Wisniewskiはい、stdcallです。 – XenoAce

関連する問題