none
problem with calling C DLL from C# - getting "NULLReferenceException was unhandled" RRS feed

  • Question

  • Hi,

    I'm trying to call a C DLL from C#.  I know this is a common question and there's lots of links out there.  I've looked through them and still run into the same questions.  First my code that's creating the problem:

    Here's an excerpt from my DLL with hopefully the relevant code needed to interpret my problem:

     

    	typdef unsigned
     int
     uint;
        __declspec(dllexport
    ) int
     __cdecl passBackUINT32Test1(uint mydata[], double
     *timepassed)
    	{
    		__int64 t1,t2;
    
    		t1=timeit();
    		for
     (int
     i=0;i<1024;i++)
    		{
    		 mydata[i]= (uint) i;
    		}
    		t2=timeit();
    
    		*timepassed = (1./2.194E3)*(t2 - t1); // in microseconds; using cpu clock frequency for conversion
    
    
    		return
     1;
    	}
    
    

     

    My C# excerpt is here:

     

    using
    
     System;
    using
    
     System.Reflection;
    using
    
     System.Runtime.InteropServices;
    using
    
     System.Diagnostics;
    
    namespace
    
     CallingCplusDLLfromCsharp
    {
     public
    
     class
    
     BenchmarksDLLImports
     {
     [DllImport("BenchmarkingThroughDLLInterface.dll"
    , EntryPoint="passBackUINT32Test1"
    , CallingConvention = CallingConvention.Cdecl)]
      public
     static
     extern
     Int32 passBackUINT32Test1(UInt16[] mydata, ref
     double
     outputTimePassed);
     }
     public
     class
     Program
     {
     static
     void
     Main(string
    [] args)
     {
      Stopwatch st = new
     Stopwatch();
      UInt16[] myarray = new
     UInt16[1024];
      Int32 ret;
      double
     outputTimePassed = new
     double
    ();
      Console.WriteLine("Going in!"
    );
      st.Start();
      ret = BenchmarksDLLImports.passBackUINT32Test1(myarray, ref
     outputTimePassed);
      st.Stop();
      Console.WriteLine("Time Elapsed = {0}\n"
    , st.Elapsed.ToString());
      Console.ReadLine();
     }
     }
    }
    
    

     

    Now I actually get my runtime error on the Console.WriteLine statement:

    "NULLReferenceException was unhandled"

    However, I'm pretty sure the problem is the DLL call before it, since I can execute "st.Elapsed.ToString()" in the Watch window just fine.

    I have a couple questions, although they might be the same question!

    1) What am I doing wrong above?

    2) And whether or not I'm setting up the DLL call portion correctly, when does one need to use the Marshal class?  I found this PDF link called "Calling C Library DLLs from C#" which gives some nice examples of passing scalars and arrays, but only saw the Marshal class used with structures (structs).   Most of my application involves passing int arrays and double arrays into DLL functions for processing and pass back.  Do I use Marshal/fixed blocks for this?   If so, I don't get why that article doesn't need them.

    Thanks in advance for any help on this.

    Best,

    Hyped

    • Edited by Hyped1107 Friday, January 14, 2011 7:48 PM fixed code formatting
    Friday, January 14, 2011 7:31 PM

Answers

  • I do see one issue that stands out. In the .Net code you are passing a short array while in the C code you are expecting a uint array.  You will be going outside the bounds of the array in your loop in C code.

     

     

     

    Saturday, January 15, 2011 3:43 AM

All replies

  • I do see one issue that stands out. In the .Net code you are passing a short array while in the C code you are expecting a uint array.  You will be going outside the bounds of the array in your loop in C code.

     

     

     

    Saturday, January 15, 2011 3:43 AM
  • Thanks AbdElRaheim, that indeed was the problem.

    I'm wondering if you have any comments in regard to my second question.  That is, at what times do I need to fix/marshal arrays that I feed into DLLs for processing and passback?  My confusion arises from the fact that the above PDF link, which looks like a reputable writeup from an Algorithm group, shows many examples of passing arrays into DLLs without the Marshal class, nor with and fixed {} blocks.

     

    Thanks again though for you response to the error in my code.

    Best,

    Hyped

    Sunday, January 16, 2011 12:45 AM
  • Marshalling happens automatically.  Use the marshal class for special cases.  Example would be if you have a method with the signature below.

    void UnmanagedSomething ( IntPtr data, int length);

    You can use the marshal class to copy a structure and then pass a pointer in.  If you had an array you could use the fixed keyword and then get a pointer to the start of the array and pass that into the method.  The p/invoke method that you have can be rewritten in several ways.  In most cases you dont need to use the marshal class.

    Default Marshaling Behavior

    http://msdn.microsoft.com/en-us/library/zah6xy75.aspx

    Sunday, January 16, 2011 12:54 AM