4

アンマネージコードからマネージコードへの文字列の受け渡しに問題があります。私のアンマネージクラス(unmanagedClass.cpp)には、マネージコードから関数へのポインターがあります。

TESTCALLBACK_FUNCTION testCbFunc;

TESTCALLBACK_FUNCTIONは1つの文字列を受け取り、何も返しません。

typedef void (*TESTCALLBACK_FUNCTION )(char* msg);

アンマネージクラスは、メソッドが1つしかないITestインターフェイスから継承します。

    STDMETHOD(put_TestCallBack) (THIS_
                  LPVOID FnAddress       
             ) PURE;

managedClass.csで、次のコードを記述します。

public class ManagedClass
{
    ITest unmanaged = new unmanagedClass();
    public delegate void TestDelegate(string info);
    ManagedClass()
    {
        unmanaged.put_TestCallBack(new TestDelegate(this.Test));
    }
    void Test(string info)
    {
            MessageBox.Show(info);
    }
}

[ComImport, Guid("<my guid here>")]
public class unmanagedClass
{
}

[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("<my guid here>"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITest
{
    [PreserveSig]
    int put_TestCallBack([MarshalAs(UnmanagedType.FunctionPtr), In] Capture.TestDelegate func);

}

管理されていないコードからTestfuncを呼び出すには、これを使用します

(*testCbFunc)("Func Uragan33::Execute has been started!");

しかし、managedClass.csのTestメソッドが呼び出されると、常にnull文字列を受け取りました。なぜそれが起こるのですか?

少し早いですがお礼を!

4

1 に答える 1

5

呼び出し規約に不一致があります。C ++コードのtypedefは、デフォルトの呼び出し規約である__cdeclを使用して関数ポインターを宣言します。ただし、マネージコードのデリゲートのデフォルトは__stdcallです。

それ以外の場合は、ピンボークマーシャラーに通知するための属性が必要になります。次のようにします。

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void TestDelegate(string info);

[MarshalAs]を関数宣言にドロップします。可能であれば、C ++コードのtypedefを修正することをお勧めします。すべての一貫性を明確にすることが、推奨される解決策です。

    typedef void (__stdcall * TESTCALLBACK_FUNCTION )(char* msg);

無関係ですが、これは修正する必要のあるバグです。

   unmanaged.put_TestCallBack(new TestDelegate(this.Test));

作成したデリゲートオブジェクトは、ガベージコレクタに表示されません。次のGCで収集される場合、ネイティブコードがコールバックを行うときにコードがクラッシュします。GCが常に参照を参照できるように、デリゲートオブジェクトをどこかに保存する必要があります。クラス内のフィールドとして、クラスオブジェクトが十分に長く存続する必要があるという追加の要件がある場合、または静的変数内のいずれか。

デリゲートの代わりにコールバックインターフェイスを宣言すると、これらの問題がすべて解消されることに注意してください。COMの方法。

于 2013-03-18T15:52:42.790 に答える