2011-09-11 11 views
5

いくつかのインターフェイスを公開するアンマネージライブラリがあります。ユーザーはインターフェイスを実装し、カスタム実装でライブラリに貼り付けることができます。アンマネージインターフェイスで管理されたラッピング

このライブラリの管理対象ラッパーを提供したいと思います。 管理されていないインターフェイスを管理されたインターフェイスでラップするのは簡単です。しかし、私の場合は、さまざまなインターフェイスのユーザー実装をサポートしたいと考えています。つまり、ライブラリのアンマネージ部分の深みにインターフェイスを送信する前に、管理されたインターフェイスの実装を取り、アンマネージドの相手を使用してラップする必要があります。

私が何かしようとした:

class UnmanagedWrapper { 
DoSomething() {m_clr.DoSomething();} 
IManaged^ m_clr; 
} 

をしかし、私は管理対象外のクラス内のメンバーを管理していることができない、コンパイラが当然と主張しました。

私はここで何でもできますか?

+1

コンテキストが不十分です。 gcroot <>またはMarshal :: GetFunctionPointerForDelegate()を使用します。 –

答えて

0

ここでは、1つのライブラリが管理されておらず、管理対象言語がそれらのライブラリを使用している場合の回避策に関する関連情報を示します。

この情報の内容は、Visual StudioでGoogleTestを使用する方法です:

Getting started with Google C++ Testing Framework

重要事項のVisual C++ユーザーのためのあなたは ライブラリにテストを入れて、あなたのmain()の場合関数が異なるライブラリまたは .exeファイルにある場合、これらのテストは実行されません。理由は、Visual C++のバグです。テストを定義すると、Google Testは特定の静的 オブジェクトを登録して登録します。これらのオブジェクトは他の場所で から参照されませんが、コンストラクタはまだ実行されています。 Visual C++リンカーは、ライブラリ内の何も参照されず、 他の場所から参照されていると判断すると、ライブラリがスローされます。メインプログラムのテストで ライブラリを参照して、 のリンカがそれを破棄しないようにする必要があります。ここでそれを行う方法です。どこか自分のライブラリのコード で関数を宣言します。

__declspec (dllexport) int PullInMyLibrary() { return 0; }

あなたは静的ライブラリ(DLLではない)にテストを置くならば、__declspec(のdllexport)は

必要とされていません。

int PullInMyLibrary(); 
    static int dummy = PullInMyLibrary(); 

これは 参照テストを続け、彼らは 起動時に自身を登録行います:今、あなたのメインプログラムでは、機能 を呼び出すコードを記述します。

さらに、静的ライブラリでテストを定義する場合は、メインプログラムのリンカオプションに /OPT:NOREFを追加します。 MSVC++ IDEを使用している場合は、 .exeプロジェクトプロパティ/構成 プロパティ/リンカー/最適化に移動し、参照設定を保持するように設定してください 参照されていないデータ(/ OPT:NOREF)。これにより、 のVisual C++リンカーは、最後の 実行可能ファイルからテストによって生成された個々のシンボルを破棄します。

もう1つの落とし穴があります。 Googleテストを静的な ライブラリ(これはgtest.vcprojで定義されています)として使用する場合、テストは も静的ライブラリに存在する必要があります。それらをDLLに含める必要がある場合は、 をGoogleテストに変更してDLLに組み込む必要があります。それ以外の場合は テストが正しく実行されないか、まったく実行されません。一般 結論はここにあります:あなたの人生を楽にしてください - 図書館であなたのテストを書いてはいけません!

0

たぶんgcroot<>が何をしたいです:

class UnmanagedWrapper { 
    DoSomething() {m_clr.DoSomething();} 
    gcroot<IManaged^> m_clr; 
} 
0

あなたがC#の.NETアプリに自分のアンマネージドDLLをインポートする必要があります。私の例は構造体へのポインタを返しますが、あなたのアプリケーションに必要な他の戻り値の型を提供することができます。 dumpbin.exe/EXPORTSを使用して、関数/ EntryPoint名全体をdllから取得してください。ここに私のクラス全体がある:

using System; 
using System.Runtime.InteropServices; 

namespace aviationLib 
{ 
    public struct MAGtype_GeoMagneticElements 
    { 
     public double Decl; /* 1. Angle between the magnetic field vector and true north, positive east*/ 
     public double Incl; /*2. Angle between the magnetic field vector and the horizontal plane, positive down*/ 
     public double F; /*3. Magnetic Field Strength*/ 
     public double H; /*4. Horizontal Magnetic Field Strength*/ 
     public double X; /*5. Northern component of the magnetic field vector*/ 
     public double Y; /*6. Eastern component of the magnetic field vector*/ 
     public double Z; /*7. Downward component of the magnetic field vector*/ 
     public double GV; /*8. The Grid Variation*/ 
     public double Decldot; /*9. Yearly Rate of change in declination*/ 
     public double Incldot; /*10. Yearly Rate of change in inclination*/ 
     public double Fdot; /*11. Yearly rate of change in Magnetic field strength*/ 
     public double Hdot; /*12. Yearly rate of change in horizontal field strength*/ 
     public double Xdot; /*13. Yearly rate of change in the northern component*/ 
     public double Ydot; /*14. Yearly rate of change in the eastern component*/ 
     public double Zdot; /*15. Yearly rate of change in the downward component*/ 
     public double GVdot; /*16. Yearly rate of change in grid variation*/ 
    }; 

    public class Declination 
    { 
     [DllImport("wmm.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "[email protected]@[email protected]@[email protected]")] 
     public static extern IntPtr GeoMagneticElements(float sdate, int igdgc, int units, float alt, float latitude, float longitude); 

     public MAGtype_GeoMagneticElements e; 

     public MAGtype_GeoMagneticElements MagDeclination(float decimalLat, float decimalLon) 
     { 

      try 
      { 
       String d = DateTime.Now.Year.ToString("D4") + '.' + DateTime.Now.Day.ToString("D1"); 
       IntPtr pnt = GeoMagneticElements((float)Convert.ToDouble(d), 1, 3, 3000.0f, decimalLat, decimalLon); 
       e = Marshal.PtrToStructure<MAGtype_GeoMagneticElements>(pnt); 
      } 
      catch (System.EntryPointNotFoundException se) 
      { 
       Console.WriteLine(se.Message); 
      } 

      return e; 
     } 
    } 
} 

ワード設定は、DLLは、32ビット、その後.NETが同様である必要がありますされるので、もし、管理対象および管理対象外の両方で同じにする必要があります。