locked
NullReferenceException when calling a method using Reflection. RRS feed

  • Question

  • I am writing a C# DLL that will call a 3rd Party DLL using Reflection.

    The 3rd Party DLL is called MorphoMyKad.dll with Namespace: -MorphoMyKad, Class Name:- MyKad

    My Program in C#:

    public class CSharpFunctions2
        {
            int intVal;
            byte[] RightMinutiae;
            byte[] LeftMinutiae;
            object obj;
            Assembly a;
            Type t;
    
            public CSharpFunctions2()
            {
                String Path = "D:\\MyDLL\\MorphoMyKad.dll";
                a = Assembly.LoadFrom(Path);            
                t = a.GetType("MorphoMyKad.MyKad");
                obj = Activator.CreateInstance(t);
                Console.WriteLine("DLL Loaded Successfully");
                RightMinutiae = new byte[511];
                LeftMinutiae = new byte[511];
            }
    
           public void DspHelloMsg()
            {
                String s = string.Empty;
                String idNo=string.Empty;
                String icName = string.Empty;
                int rtn;
    
                Console.WriteLine("Calling Sagem");
                rtn = Sagem_Connect("a");
                Console.WriteLine("Sagem Connect called rtn=" + rtn);
                if (rtn == 0)
                {
                    Console.WriteLine("Sagem Connected");
                    idNo = Sagem_GetIDNumber();
                    icName = Sagem_GetGMPCName();
                    Console.WriteLine("MyKad No- " + idNo);
                    Console.WriteLine("Name- " + icName);
                    //SagemMyKad.GetMinutiae();
                    rtn = (int)t.InvokeMember("GetMinutiae",
                           BindingFlags.InvokeMethod |
                           BindingFlags.Instance |
                           BindingFlags.Public, 
                           null, obj, null);
                    Console.WriteLine("Sagem GetMinutiae. rtn=" + rtn);
                }
                else
                {
                    Console.WriteLine("Sagem Connect Failed. rtn=" + rtn);
                }
                rtn = Sagem_Disconnect();
                Console.WriteLine("Sagem Disconnect. rtn=" + rtn);
            }
    
            private int Sagem_Connect(string rdr)
            {
                int connResult = 0;
                connResult = (int)t.InvokeMember("Connect",
                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                null, obj, new object[] { rdr });
                return connResult;
            }
    
            private string Sagem_GetIDNumber()
            {
                String idNo = string.Empty;
    
                idNo = (string)t.InvokeMember("GetIDNumber",
                       BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                       null, obj, null);
                return idNo;
               
            }
    
            private string Sagem_GetGMPCName()
            {
                String icName = string.Empty;
    
                icName = (string)t.InvokeMember("GetGMPCName",
                         BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                         null, obj, null);
                return icName;
            }
    
            private int Sagem_Disconnect()
            {
                int connResult = 0;
                connResult = (int)t.InvokeMember("Disconnect",
                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                null, obj, null);
                return connResult;
            }

    The Problems

    It all runs well until in Invoked the GetMinutiae method.

    The program crash and display:-

    Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
       at CSharpDLL2.CSharpFunctions2.DspHelloMsg() in D:\...\CSharpDLL2\CSharpFunctions2.cs:line 51
       at ConsoleApplication1.Program.Main(String[] args) in D:\..\CSharp2\CSharpDLL2\ConsoleApplication1\Program.cs:line 17
    

    The GetMinutiae actually read the Thumbprint data from the physical smartcard and loaded them into 2 properties

    public byte[] RightFinger_Byte {get; set}

    public byte[] LeftFinger_Byte {get; set}

    My Questions:-

    1) Why calling the GetMinutiae will crash the program but others OK?

    2) How to assign the RightFinger_Byte and LeftFinger_Byte into  byte[] RightMinutiae & byte[] LeftMinutiae;

    Thanks.

     


    Thank You

    Monday, October 12, 2015 1:08 PM

Answers

  • Greetings KRGuy.

    Are you sure that GetMinutiae() returns an int? I notice that in the non-reflection version, you are not trying to save the return value. But in the reflection version you are trying to save it as an int.

    If GetMinutiae() returns void and you try to cast it to int, that could explain the error.

    • Marked as answer by KRGuy Tuesday, October 20, 2015 12:27 PM
    Monday, October 19, 2015 4:05 AM

All replies

  • 1. From that data I would say t is null when you try to use it. There are no other uses of the variable t, so wich other instance of it being used succeed?
    You should consider moving a not null check into the constructor, right after you assign that variable. No point in calling the rest of the code if loading the dll fails.

    Also using a single char as a variable name is a incredibly bad idea, unless it is a loops running integer variable.

    Doesn't that DLL support .COM interop?

    Monday, October 12, 2015 2:18 PM
  • Hi Christopher84,

    The "t" was used in 2 previous calls to Sagem_GetIDNumber() and Sagem_GetGMPCName() which runs correctly.
    It was when tried to call GetMinutiae that it crash
    I suspect that the GetMinutiae is loading some data from the Smart Card to its memory.

    I not sure how to check whether the DLL support .COM interop.

    Followings is the program written in C# without using reflection:- 

       public class SagemCardReader
        {
            MorphoMyKad.MyKad SagemMyKad;
            byte[] RightMinutiae;
            byte[] LeftMinutiae;
    
            public SagemCardReader()
            {
                SagemMyKad = new MorphoMyKad.MyKad();
                RightMinutiae = new byte[511];
                LeftMinutiae = new byte[511];
            }
    
            public int ReadCard2(ref string idNo, ref string icName)
            {
                int connResult = 0;
    
                connResult = SagemMyKad.Connect("a");
                if (connResult == 0)
                {
                    idNo = SagemMyKad.GetIDNumber();
                    icName = SagemMyKad.GetGMPCName();
                    SagemMyKad.GetMinutiae();
                    if (SagemMyKad.LeftFinger_Byte != null)
                    {
                        LeftMinutiae = SagemMyKad.LeftFinger_Byte;
                    }
                    if (SagemMyKad.LeftFinger_Byte != null)
                    {
                        RightMinutiae = SagemMyKad.RightFinger_Byte;
                    }
                }
    
                SagemMyKad.Disconnect();
    
                return connResult;
            }
    
            public int VerifyThumb()
            {
                int MatchResult = 0;
                byte[] tempByte;
    
                try
                {
                    tempByte = new byte[511];
                    if ((RightMinutiae != null) && (LeftMinutiae != null))
                    {
                        tempByte = LeftMinutiae;
                        MatchResult = SagemMyKad.MatchNoDialog(tempByte, tempByte, "", 1, 10);
                        if (MatchResult != 0)
                        {
                            tempByte = RightMinutiae;
                            MatchResult = SagemMyKad.MatchNoDialog(tempByte, tempByte, "", 1, 10);
                        }
                    }
                    else
                    {
                        MatchResult = -2;
                    }
    
                }
                catch (Exception ex)
                {
                    String str = ex.Message;
                    MatchResult = -1;
                }
                return MatchResult;
            }
        }

    Thanks.


    Thank You

    Friday, October 16, 2015 4:47 AM
  • Hi KRGuy,

    Actually, I don't think we can figure out the cause with so limited information about the third party dll. I would suggest you try to debug the crashed application with debug tools and provide more information so others might help you out.

    Have a nice day!

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    • Edited by Kristin Xie Monday, October 19, 2015 3:05 AM
    Monday, October 19, 2015 3:04 AM
  • Hi Kristin,

    Can you point me to the location that I can download and learn to use the debug tools?

    Thanks.


    Thank You

    Monday, October 19, 2015 3:24 AM
  • Hi Kristin,

    Can you point me to the location that I can download and learn to use the debug tools?

    Thanks.


    Thank You

    Please check this page.

    https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

    Note the 3 ways to get Debugging Tools for Windows section.

    https://msdn.microsoft.com/en-us/windows/hardware/hh852365.aspx

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, October 19, 2015 3:38 AM
  • Greetings KRGuy.

    Are you sure that GetMinutiae() returns an int? I notice that in the non-reflection version, you are not trying to save the return value. But in the reflection version you are trying to save it as an int.

    If GetMinutiae() returns void and you try to cast it to int, that could explain the error.

    • Marked as answer by KRGuy Tuesday, October 20, 2015 12:27 PM
    Monday, October 19, 2015 4:05 AM
  • Hi Ante,

    Thanks for the hints.

    I just need to take out the return value from the followings:-

    rtn = (int)t.InvokeMember("GetMinutiae",
                           BindingFlags.InvokeMethod |
                           BindingFlags.Instance |
                           BindingFlags.Public,
                           null, obj, null);

    change to

    t.InvokeMember("GetMinutiae",
                           BindingFlags.InvokeMethod |
                           BindingFlags.Instance |
                           BindingFlags.Public,
                           null, obj, null);

    The program runs without any errors.

    Thanks.


    Thank You

    Tuesday, October 20, 2015 12:32 PM