1

私は .NET スマート カードを使用しています。.NET リモート処理と同じ概念を持っています。

したがって、私のスマートカード (サーバーとして) には次のサービスがあります。

public class MyService : MarshalByRefObject
{
     string a = "abC";

    public byte[] MySampleMethod()
    {
        MyService obj = new MyService();
        return help.ObjectToByteArray( obj);
    }}}

これは ObjectToByteArray(obj) です

public static byte[] ObjectToByteArray(MyService obj)
    {
        if (obj == null)
            return null;
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream(0);
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }

クライアントに関して:

    public static void Main()
    {
        // create and register communication channel
        APDUClientChannel channel = new APDUClientChannel();
        ChannelServices.RegisterChannel(channel);

        // get the referenc to remote object
        MyService service = (MyService)Activator.GetObject(typeof(MyService), URL);

        // invoke the remote method
        byte[] result = service.MySampleMethod();

        MyService obj = ByteArrayToObject(result);

        Console.WriteLine(result[0]);
        Console.ReadLine();
        // unregister the communication channel
        ChannelServices.UnregisterChannel(channel);
    }

ByteArrayToObject

    public static MyService ByteArrayToObject(byte[] arrBytes)
    {
        MemoryStream memStream = new MemoryStream(0);
        BinaryFormatter binForm = new BinaryFormatter();
        memStream.Write(arrBytes, 0, arrBytes.Length);

        memStream.Seek(0, SeekOrigin.Begin);
        //memStream.Position = 0;
        MyService obj = (MyService)binForm.Deserialize(memStream);
        return obj;
    }

問題は、オブジェクトをデシリアライズしたいときです。

この文字列 "ABCDE" をテストし、カードにシリアル化すると、結果の 16 進数は次のようになります。

1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05-00-00-00-01-41-00-42-00-43-00- 44-00‌ -45-00

PCでシリアル化したときの結果は次のとおりです。

00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-00-06-01-00-00-00-05-41-42- 43-44‌ -45-0B。

したがって、私の PC アプリケーションでは、2 番目の文字列の逆シリアル化はうまく機能しますが、最初の文字列 (スマート カードから) を逆シリアル化すると、次のようになりました。

「入力ストリームは有効なバイナリ形式ではありません。開始内容 (バイト単位) は次のとおりです: 1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05- 00-00...」

4

1 に答える 1

2

Gemalto.NET スマート カードは、参照によるマーシャリングのみをサポートします。そのため、サーバーにあるプリミティブ型と構造体型は、シリアル化を必要とせずにクライアントでアクセスできます。これは、リモート呼び出しによるオブジェクトへの参照が既にあるためです。

最初にサービスを登録します。

public class MyServer
    {
        /// <summary>
        /// specify the exposed remote object URI.
        /// </summary>
        private const string REMOTE_OBJECT_URI = "MyService.uri";

        /// <summary>
        /// Register the server onto the card.
        /// </summary>
        /// <returns></returns>
        public static int Main()
        {
            // Register the channel the server will be listening to.
            ChannelServices.RegisterChannel(new APDUServerChannel());

            // Register this application as a server            
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyService), REMOTE_OBJECT_URI, WellKnownObjectMode.Singleton);

            return 0;
        }
    }

次に、サービス クラスを定義すると、gemalto ドキュメントのプリミティブ型と構造体を返すことができます。

マーシャリングできる型には、基本的な値の型 (byte、short、char、int、long、string など)、構造体、基本型の配列、および MemoryStreams が含まれます。

public class MyService : MarshalByRefObject
    {
        public struct Person
        {
            public string name;
            public int id;

            public Person(int id, string name)
            {
                this.name = name;
                this.id = id;
            }

            public string getName()
            {
                return this.name;
            }

            public int getId()
            {
                return this.id;
            }
        }

        public string MySampleMethod()
        {
            return "This is return String";
        }

        public Person getPerson()
        {
            Person person = new Person(15, "Wajdy");
            return person;
        }
    }

クライアント アプリケーションでは、サービス オブジェクトへの参照を取得し、メソッドを通常どおり呼び出すことができます。

public class MyClient
    {
        private const string URL = "apdu://selfdiscover/MyService.uri";

        public static void Main()
        {
            // create and register communication channel
            APDUClientChannel channel = new APDUClientChannel();
            ChannelServices.RegisterChannel(channel);

            // get the referenc to remote object
            MyService service = (MyService)Activator.GetObject(typeof(MyService), URL);
            Console.WriteLine(service.MySampleMethod());

            MyService.Person person = service.getPerson();
            Console.WriteLine(person.getName());
            Console.WriteLine(person.getId());

            Console.ReadLine();

            // unregister the communication channel
            ChannelServices.UnregisterChannel(channel);
        }
    }
于 2013-04-09T08:00:03.610 に答える