C++/CLI包装程序不工作(LoaderLock异常)



我为非托管C++库(与C#一起使用)制作了非常简单的包装器。Wrapper有一个非托管类和一个托管类。托管类具有属于非托管类的私有成员,并以此方式使用它。

我做了一个非常简单的设置——我只为一个函数创建了包装器,看看是否一切正常。但当我创建包装器的实例时,我的应用程序get的异常"LoaderLock被检测到",并显示以下消息:

DLL"c:\path\CPPWrapper.DLL"是尝试在OS Loader锁内进行托管执行。不要尝试在DllMain或映像初始化函数内运行托管代码因为这样做可能会导致应用程序挂起。

如果我关闭"LoaderLock"异常的中断,我会得到"FileLoadException未处理":

Could not load file or assembly 'CPPWrapper.dll' or one of its dependencies. Exception from HRESULT: 0xE0434352

知道我做错了什么吗?我该如何解决这个问题?

CPP说唱歌手.h

// CPPWrapper.h
#pragma once
#include "Native.h"
using namespace System;
namespace CPPWrapper {
    public ref class Class1
    {
        public:
        Class1() : mnt(new Native)
        {
        }
        ~Class1(void)
        {
            // call the finalize method
            this->!Class1();
        }
        // Finalize (for garbage collection)
        !Class1(void)
        {
            // Remove unmanaged class
            delete mnt;
            mnt = NULL;
        }
        void Napravi()
        {
            mnt->CreatePK();
        }
    private:
        Native *mnt;
    };
}

我发现解决此问题的正确方法是在dllmain.c中添加#pragma unmanaged。不要为"LoaderLock"异常关闭中断。

有关详细信息,请参阅混合程序集的初始化并向下滚动到DllMain部分。基本上,项目正在将DllMain函数编译为托管(MSIL),但它只在非托管代码中运行。此#pragma unmanaged强制将函数编译为非托管函数。

所以我的dllmain.c现在是:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#pragma unmanaged
BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved
                 )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
LoaderLock的另一个潜在原因是初始化全局静态对象。在我的案例中,我正在全局编译boost::expression regex,当我的C++/CLI包装程序初始化DllMain时,它不喜欢这样做。我不知道为什么,因为它不应该是托管代码,但将它移到函数静态对象中修复了它。

相关内容

  • 没有找到相关文章

最新更新