0

In my C# program, I'm making a call to the AT91Boot_Scan function in sam-ba.dll. In the documentation for this DLL, the signature for this function is void AT91Boot_Scan(char *pDevList)

Unfortunately, no matter what I try I keep getting EntryPointNotFoundException and ArgumentNullException errors:

Exception thrown at 0x75E3C54F in MyApp.exe: Microsoft C++ exception: EEMessageException at memory location 0x0038E304.
Exception thrown: 'System.EntryPointNotFoundException' in MyApp.exe
Unable to find an entry point named 'AT91Boot_Scan' in DLL 'sam-ba.dll'.
Exception thrown: 'System.ArgumentNullException' in System.Windows.Forms.dll

My code is as follows, what am I doing wrong?

[DllImport("sam-ba.dll")]
unsafe public static extern void AT91Boot_Scan(char* pDevList);

unsafe private string[] LoadDeviceList()
    {
        const int MAX_NUM_DEVICES = 10;
        const int BYTES_PER_DEVICE_NAME = 100;

        string[] deviceNames = new string[MAX_NUM_DEVICES];

        try
        {
            unsafe
            {
                // A pointer to an array of pointers of size MAX_NUM_DEVICES
                byte** deviceList = stackalloc byte*[MAX_NUM_DEVICES];

                for (int n = 0; n < MAX_NUM_DEVICES; n++)
                {
                    // A pointer to a buffer of size 100
                    byte* deviceNameBuffer = stackalloc byte[100];
                    deviceList[n] = deviceNameBuffer;
                }

                // Is casting byte** to char* even legal?
                AT91Boot_Scan((char*)deviceList); 

                // Read back out the names by converting the bytes to strings
                for (int n = 0; n < MAX_NUM_DEVICES; n++)
                {
                    byte[] nameAsBytes = new byte[BYTES_PER_DEVICE_NAME];
                    Marshal.Copy((IntPtr)deviceList[n], nameAsBytes, 0, BYTES_PER_DEVICE_NAME);

                    string nameAsString = System.Text.Encoding.UTF8.GetString(nameAsBytes);
                    deviceNames[n] = nameAsString;
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        return deviceNames;
    }
Calseon
  • 325
  • 3
  • 18
  • Your title and one of the tags you chose indicate `C#` but the code and messages look like `C++` -- which is it? – David Tansey Mar 01 '17 at 22:07
  • It's C# code calling a DLL (which I think is written in C++) Is there anything I can do to clear up confusion in my post? – Calseon Mar 01 '17 at 22:10
  • 1
    A C# console app typically requires an entry point called `Main()` see the following [MSDN article](https://msdn.microsoft.com/en-us/library/system.entrypointnotfoundexception(v=vs.110).aspx) which talks about `System.EntryPointNotFoundException` -- especially the first couple of points under **Remarks**. Resolving this will fix at least one of the problems you are experiencing. – David Tansey Mar 01 '17 at 22:14
  • Hmm I'm actually making a Windows Form App using Visual Studio, so the `Main()` method is there in `Program.cs`. I think my problem is that it's not finding the function `AT91Boot_Scan` in the DLL I'm using...Nonetheless the other points under Remarks raised some interesting points like decorated names...I'll try that out. Thanks! – Calseon Mar 01 '17 at 22:26
  • 2
    I looked more closely at some of the doc for `sam-ba.dll` and it seems that this DLL is a COM / OLE object. I was able to add a reference to the TLB file `SAMBA_DLL.tlb`, add a `using SAMBA_DLLLib;` and then instantiate an object from that with `SAMBA_DLLLib.ISAMBADLL mySamba = new SAMBA_DLLLib.SAMBADLL();` Then when I work with that object variable `mySamba.` at design-time, Intellisense 'knows' what the methods and signatures look like, including the `AT91Boot_Scan()` method you are interested in. I think this is the way you want to go with this particular DLL and C#. – David Tansey Mar 01 '17 at 23:50
  • You're right, adding the reference that way works. Thanks a ton! – Calseon Mar 02 '17 at 14:10

1 Answers1

0

Following David Tansey's solution in the comments, the way I should've gone about doing this was adding sam-ba.dll as a COM reference (Solution Explorer > References > Add References > Browse). Then just instantiating a ISAMBADLL class object and calling the methods through that class.

Calseon
  • 325
  • 3
  • 18