3
votes

I am creating an Autodesk Revit add-in in C#. Output of this project is a DLL itself. Within this project, I am loading another unmanaged DLL by calling:

IntPtr pDll = LoadLibrary("E:\\Rep3DLib\\builds\\Release\\Index.dll"); int a = Marshal.GetLastWin32Error();

Within debugger, I see that pDll has value 0 and a has value 127 (Error: The specified procedure could not be found.). This is surprising because I am not even looking any particular procedure within the DLL. I just want to load the DLL.

Now I delete the unmanaged DLL from E:\\Rep3DLib\\builds\\Release\\Index.dll and in the above code, a has value 126 (Error: The specified module could not be found.). This does make sense. It also means that when the DLL is present at the correct location, the code is able to find it but somehow it's looking for a procedure which it's not able to find.

To debug this problem, I created another project within the same solution. Here's the code for this project:

namespace testIndex {
    class Program {

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        static void Main(string[] args) {
            IntPtr pDll = LoadLibrary("E:\\Rep3DLib\\builds\\Release\\Index.dll");
            int a = Marshal.GetLastWin32Error();
        }
    }
}

When I run this, pDll has a non-zero value and I am able to call the functions defined within the Index.dll.

Note that both the projects have target platform as x64. I also verified that if I build the Revit add-in and run it on a different machine, it does find the DLL. So somehow it's not finding the DLL only on my machine although the path E:\\Rep3DLib\\builds\\Release\\Index.dll is definitely correct.

Any idea what could be wrong?

1
what about pinvoke?Daniel A. White
I am new to C# and .Net. I am guessing that PInvoke uses DllImport, am I correct? In any case, before using LoadLibrary(), I was using DllImport directly. In other words, I had: ` [DllImport("Index.dll")] private static extern IntPtr createIndex(float spacing, IntPtr errorCode);` After calling createIndex(), I was getting the error that Index.dll could not be found. This was even if I was calling SetDllDirectory("E:\\Rep3DLib\\builds\\Release"); before calling createIndex(). I switched to LoadLibrary() because I thought it would be easier to debug.Neerav Mehta
Could the dll on your machine be corrupt?Sam Axe
Sam, if that were the case, the code in second project shouldn't work as well, right? But code in the second project is working perfectly.Neerav Mehta
Could the path you hand to LoadLibrary be mistyped in the plugin project? Or perhaps the path contains a misspelling in the filesystem (eg. a directory is misspelled) ?Sam Axe

1 Answers

0
votes

Here's the answer to the question I posted above. My add-in was using a dependent DLL named "pcl_features_release.dll". Revit was loading another add-in before mine, which was also loading its own "pcl_features_release.dll" which might be slightly different than mine. As a result, although Revit was finding my DLL, it was not able to load it.

Another question: In this case, two add-ins are dependent on "pcl_features_release.dll", which is a DLL supplied by Point Cloud Library (http://pointclouds.org/). What is the best practice to avoid conflict in such cases. I can not change someone else's add-in. How do I make sure that my add-in loads my "pcl_features_release.dll" that is being supplied with the add-in?