0
 int Set(CANMsg &CANObj)

上記のメソッドを c# から呼び出す必要があります。今まで私はラッパーを定義しました:

 extern "C" __declspec(dllexport) int SetWrapper(CANMsg CANObj);

CANMsg CANObj --- このパラメーターは問題ありませんか、それとも CANMsg *CANObj を使用する必要がありますか?

そしてここで私はラッパーを実装します:

 extern "C" __declspec(dllexport) int SetWrapper(CANMsg CANObj)
 { 
      return Set(CANObj);
 }

これは関数のオーバーロードされたバージョンであり、何とか違いを生む必要があったため、このラッパーを作成しています。

CANMsg クラスは次のとおりです。

 class CANMsg
 {
 public:
 CANMsg();
 ~CANMsg();

 void AddRef() const;
 void Release() const;
 unsigned int MsgId;
 unsigned int DLC;
 unsigned int Handle;
 unsigned int Interval;
 unsigned int TimeStamp;
 unsigned char Data0;
 unsigned char Data1;
 unsigned char Data2;
 unsigned char Data3;
 unsigned char Data4;
 unsigned char Data5;
 unsigned char Data6;
 unsigned char Data7;

  protected:

mutable int refCount;  

};

今、C#で私は次のものを持っています:

      [StructLayout(LayoutKind.Sequential)]
      public class CANmsg
   {
      public  int MsgId;
      public int DLC;
      public int Handle;
      public int Interval;
      public int TimeStamp;
      public char Data0;
      public char Data1;
      public char Data2;
      public char Data3;
      public char Data4;
      public char Data5;
      public char Data6;
      public char Data7;
   }

インポートは次のようになります。

     [DllImport("engine.dll", CallingConvention = CallingConvention.Cdecl)]
  [return: MarshalAs(UnmanagedType.I4)]
  public static extern int SetWrapper(IntPtr canMSGObject);

そのCANMsgオブジェクトについて少し混乱しています.IntPtrとしてOKと宣言していますか、マーシャルはOKですか、それともタイプですか?そのようにすると、IntPtr で、そこでどのようなインスタンス化を実行すればよいでしょうか。CANMsg オブジェクトを送信すると、無効な引数に関するエラーが発生します。

これについてさらに詳細が必要な場合はお知らせください。

4

2 に答える 2

1

このように C# オブジェクトをネイティブ C++ に渡すことはできません。Marshal.StructureToPtr が必要です。詳細と例はこちら

于 2013-11-07T15:06:08.827 に答える
1

あなたの C++ クラス定義を見ると、「コンストラクタとデストラクタで何が起こるのか?」と自問します。と「何をしAddRef()、何をRelease()しますか?」C# オブジェクトからその IntPtr に単純にデータを射影して最善を尽くすことはできないため、これらは重要な質問です。代わりに、この作業を行うヘルパー DLL を作成することを検討する必要があります。次のようなメソッドが必要になる場合があります。

public ref class MyLibraryHelper {

public:
    IntPtr MakeCANMsg() { return gcnew IntPtr(new CANMsg()); }
    void DestroyCANMsg(IntPtr msgPtr) {
       CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
       if (msg) delete msg;
    }
    void ProjectTo(CSharpCANMsg ^csh, IntPtr msgPtr)
    {
       CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
       if (!msg) return;
       msg->MsgId = csh->get_MsgId();
       // etc
    }
    void ProjectFrom(IntPtr msgPtr, CSharpCANMsg ^csh)
    {
       CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
       if (!msg) return;
       csh->set_MsgId(msg->MsgId);
       // etc
    }
}

私の C++/CLI は錆びているので、問題が発生することを期待してください。これがハンド マーシャリングのように見える場合は、公開したクラスが必要なように見えるからです。

正直なところ、おそらくこれは必要ありません。実際には、CANMsg を構築してそれをプライベート メンバーとして保持し、.NET プロパティを下位レベルのオブジェクトにマップする C++/CLI クラスが必要です。このタイプのクラスは使い捨てである必要があり、!ClassName()デストラクタは基になるオブジェクトを削除する責任があります。

于 2013-11-07T15:32:15.677 に答える