tags:

views:

462

answers:

3

Hello,

I have an unmanaged C++ MFC dll that was developed in VS 6.0. I would like to use it in my C# app. I'm trying to use PInvoke.

Here is the C++ code:

// testDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"


extern "C" {

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
         )
{
    return TRUE;
}

 __declspec(dllexport) int test(int a)
{
    return a * a;
}
}

And here is how I'm trying to invoke the method "test" from C#:

// PInvokeTest.cs
using System;
using System.Runtime.InteropServices;

class PlatformInvokeTest
{

    [DllImport("TestDll.dll")]
    internal static extern int test(int number);

    public static void Main()
    {
        Console.WriteLine(test(5));     
    }
}

This approach works just fine when I set C++ dll to be just a regular Win32 dll.

But once I change the project type to MFC ("Use MFC in a Shared DLL") I'm getting this error:

Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'TestDll.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) at PlatformInvokeTest.test(Int32 number)

Thanks!

+1  A: 

The DLL needs to be in a path where the system can pick it up. have you put it in the directory where your application starts ? (probably in a DEBUG folder of you VS solution).

The second option is to give it the absolute path of the DLL.

The third option is to place it in "c:\windows\System" but this is a '-1' approach :D

Hassan Syed
Thanks, Hassan.The TestDll.dll is in the bin folder (where the .exe file is). In fact when I compile TestDll.dll as regular Win32 dll and place to the same location, the program works just fine. I'm getting this error only when I'm compiling the dll as MFC.I guess it has something to do with dependencies, but I'm not sure what exactly I also should add along with MFC dll...
Michael Narinsky
+1  A: 

In general, when you hit errors like this you can use Assembly Binding Log Viewer to determine if the dll is failing to load because of a missing dependency.

In your particular case, the most probabl cause is that you are dynamically linking your dll to MFC and when the C# app attempts to load your dll, it is failing to load the MFC dlls.

You can either copy the required MFC dlls side-by-side or you can switch to statically linking MFC to your lib.

Franci Penov
A: 

TestDll.dll probably can't load one of it's dependent DLL's.

Try loading your TestDll.dll file in the Depends (Dependency Walker) utility. Depends should be installed with VC 6, under Microsoft Visual Studio 6.0 Tools. That will show you what dependencies the DLL has and will flag if one of the dependencies failed.

Make sure you load the TestDll.dll from the same folder that the C# code does.

Note that Depends only works with unmanaged DLL's.

shf301
It works!!! Thanks a lot! Dependency Walker was exactly what I needed. TestDll.dll had one dependent dll - MSVCRTD.DLL. After I copied this dll to the project folder, C# application ran just fine.
Michael Narinsky
This means you have a dependency on the C++ runtime. MSVCRTD is the debug build of the runtime. Be sure to redistribute the non-debug dll with your release build.
Aidan Ryan