包装DLL - 了解导入失败的原因

时间:2012-12-18 14:21:23

标签: c# c++ dll dllimport

背景

我有一个嵌入式系统,它运行一个最初用C ++编写并在Visual Studio中编译的应用程序,它可以生成一个可执行文件和30多个DLL。无法在VS对象浏览器或其他工具(如P / Invoke Interop Assistant)中浏览这些库。

在Dependency Walker中加载一些DLL会显示所有这些DLL在其依赖关系树中都缺少某些依赖项( cdfview.dll dwmapi.dll w32topl.dll ,...)但根据this question,这可能不是问题。

我有一些的源代码文件,以及所有编译的DLL。应用程序当前运行没有问题,表明没有真正的依赖性问题。

我试图调用一些库函数并最终使用C#创建一个包装器,但是即使是最简单的函数也无法成功导入和调用。我总是收到以下错误:

  

无法加载DLL'ldName.dll':动态链接库(DLL)   初始化例程失败。 (HRESULT异常:0x8007045A)

示例代码[已编辑]

从C ++源代码头文件中我有以下声明:

#define OB_API __declspec(dllexport) __cdecl 

typedef unsigned long DWORD;  // From windef.h
typedef DWORD OBSTATUS;

OBSTATUS OB_API TestObj(void);

在C ++源代码文件中给出了以下定义(似乎总是返回 true ):

BOOL WINAPI DllMain(HANDLE  /* hModule */, 
                      DWORD   ul_reason_for_call, 
                      LPVOID  /* lpReserved */
                      )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

在我的C#应用​​程序类中,我添加了以下声明:

[DllImport(@"dllName.dll", CallingConvention=CallingConvention.Cdecl)
public static extern ulong TestObj();

DLL和C#应用程序二进制文件位于同一目录中。

问题

通过研究错误,似乎有很多原因可以抛出这个特殊的异常,我想知道如何进一步解决这类问题。

有没有办法获得有关初始化例程失败原因的更详细信息?

(注意:目标系统正在运行.NET framework 2.0)

1 个答案:

答案 0 :(得分:4)

您要加载的DLL包含DllMain()函数。这很常见,这样的函数初始化DLL的状态。 Windows确保在DLL加载时调用此函数,它会在您第一次对该DLL导出的函数进行调整时自动执行。

问题是,该函数返回FALSE表示它无法正确初始化DLL。当然,这并没有给出关于为什么它返回FALSE的全部信息。 Windows无法执行任何操作,只会生成错误1114,ERROR_DLL_INIT_FAILED。如果DLL本身不输出任何诊断,那么除了调试代码之外你什么也做不了。从Project + Properties,Debug选项卡开始,勾选“启用非托管代码调试”选项。

手指交叉,您在“输出”窗口中看到一条消息。赔率不是很好。如果您没有DLL的源代码,那么您将需要DLL的供应商或作者的帮助。给他一份像这样失败的测试项目。