2009-12-16 103 views
1

我有一个在VS 6.0中开发的非托管C++ MFC dll。我想在我的C#应用​​程序中使用它。我正在尝试使用PInvoke。从C#调用非托管C++ VS 6.0 MFC dll

这里是C++代码:

// 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; 
} 
} 

这里是如何我试图调用从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));  
    } 
} 

当我设置这种方式工作得很好C++的DLL只是一个普通的Win32 DLL。

但是,一旦我更改项目类型MFC(“使用MFC中共享DLL”)我得到这个错误:

未处理的异常:System.DllNotFoundException:无法加载DLL“TestDll.dll ': 指定的模块无法找到。 (异常来自HRESULT:0x8007007E) at PlatformInvokeTest.test(Int32号码)

谢谢!

回答

1

TestDll.dll可能无法加载它的一个依赖DLL。

尝试在Depends(Dependency Walker)实用程序中加载您的TestDll.dll文件。应该在Microsoft Visual Studio 6.0 Tools下安装VC 6。这将告诉你什么依赖关系的DLL,并会标志如果其中一个依赖关系失败。

请确保您从C#代码所在的文件夹中加载TestDll.dll。

请注意,取决于仅适用于非托管DLL。

+0

它的工作原理!非常感谢!依赖沃克正是我所需要的。 TestDll.dll有一个相关的DLL - MSVCRTD.DLL。在将此dll复制到项目文件夹后,C#应用程序运行得很好。 – 2009-12-16 21:05:10

+0

这意味着您对C++运行时具有依赖性。 MSVCRTD是运行时的调试版本。确保使用您的发行版本来重新分发非调试dll。 – 2009-12-17 20:38:28

1

该DLL需要位于系统可以检测到的路径中。你有没有把它放在应用程序启动的目录中? (可能在VS解决方案的DEBUG文件夹中)。

第二个选项是给它的DLL的绝对路径。

第三个选项是将它放在“C:\ WINDOWS \ SYSTEM”,但是这是一个“-1”的做法:d

+0

谢谢哈桑。 TestDll.dll位于bin文件夹中(.exe文件所在的位置)。实际上,当我将TestDll.dll作为常规的Win32 dll编译并放置到同一位置时,该程序工作得很好。只有当我将MFC编译为dll时,才会出现此错误。 我想它与依赖关系有关,但我不确定究竟是什么我也应该与MFC DLL一起添加... – 2009-12-16 20:30:43

1

一般情况下,当你打象这样的错误,你可以使用Assembly Binding Log Viewer确定如果由于缺少依赖关系,DLL无法加载。

在你的特殊情况下,最可能的原因是你动态链接你的DLL到MFC,当C#应用程序尝试加载你的DLL时,它无法加载MFC DLL。

您可以并排复制所需的MFC dll,也可以切换为将MFC静态链接到lib。