无法使用C ++ / CLI包装器从C#DLL加载功能

时间:2018-07-16 12:32:47

标签: c# c++ dll c++-cli

这是我第一次使用c#dll调用函数。

我制作了一个c#包装器(c ++ / cli)以从c ++调用c#函数。这个包装器本身是一个dll,我想在我的主代码中使用。以下是wrapper.h和wrapper.cpp文件。 CSharpWrapper是继承基类ImageTool的抽象类。在头文件的末尾,我正在导出包装类的工厂。

wrapper.h

#define Export_Wrapper

#ifdef Export_Wrapper
#define _DLLExport __declspec(dllexport)
#else
#define _DLLImport __declspec(dllimport)
#endif // Export_Wrapper

class CSharpWrapperPrivate;

class _DLLExport CSharpWrapper : public ImageTool
{
public:
    CSharpWrapper();
    ~CSharpWrapper();

    int Initialize();
    int Deinitialize();
    cv::Mat AcquireImg(double positionX, double positionY);

private:
    CSharpWrapperPrivate* _private;
};

extern "C" __declspec(dllexport) ImageTool* __cdecl createFactory()
{
    return new CSharpWrapper;
}

wrapper.cpp

class CSharpWrapperPrivate
{
public:
    msclr::auto_gcroot<ImageDistiller^> ImageAPI;
};

CSharpWrapper::CSharpWrapper()
{
}

CSharpWrapper::~CSharpWrapper()
{
    delete _private;
}

int CSharpWrapper::Initialize()
{
    _private = new CSharpWrapperPrivate();
    _private->ImageAPI = gcnew ImageDistiller();
    return _private->ImageAPI->Initialize();
}

int CSharpWrapper::Deinitialize()
{
    return _private->ImageAPI->Deinitialize();
}

cv::Mat CSharpWrapper::AcquireImg(double positionX, double positionY)
{
    Mat img = _private->ImageAPI->AcquireImg(positionX, positionY);
}/**/

在wrapper.cpp文件中,Visual Studio能够建议c#dll中可用的功能。以下是main.cpp代码,我试图通过此包装器调用函数。

main.cpp

typedef ImageTool*(__cdecl *ImgFactory)();

ImageTool* instance_imgcapture;
HINSTANCE dll_imgcapture_handle;

int main()
{
    dll_imgcapture_handle = ::LoadLibrary(TEXT("wrapper.dll"));
    if (!dll_imgcapture_handle) {
        std::cerr << "Unable to load wrapper DLL!\n";
        return 1;
    }

    ImgFactory zximgcapturefactory = reinterpret_cast<ImgFactory>(::GetProcAddress(dll_imgcapture_handle, "createFactory"));
    if (!zximgcapturefactory)
    {
        std::cerr << "Unable to load factory from wrapper.dll!!\n";
        ::FreeLibrary(dll_imgcapture_handle);
        return 1;
    }

    instance_imgcapture = zximgcapturefactory();
    instance_imgcapture->Initialize();

    return 1;
}

现在,当我运行main.cpp时,它可以创建dll_imgcapture_handle和ImgFactory。但是,当调用instance_imgcapture-> Initialize()时,会出现以下错误:

wrapper.exe中0x00007FFD20B5A388(KernelBase.dll)的未处理异常:0xE0434352(参数:0xFFFFFFFF80070002、0x0000000000000000、0x0000000000000000、0x0000000000000000、0x00007FFD03580000)。

我尝试了这种方法来与其他c ++ dll一起加载dll(与main.cpp中一样)-它可以工作。 我尝试使用dependency_walker检查是否有任何缺少的dll-没有。 我已经包含了正确的opencv库,它们可以正常工作。我已经在项目属性中包括了dll和libs的路径,并在Linker-> Input中添加了lib名称。

能帮我调试这个问题吗?

1 个答案:

答案 0 :(得分:1)

这是与依赖项有关的错误。由于我试图从非托管方式调用托管代码,因此调试器生成的输出未明确提及该错误,而仅输出“ 0x00处未处理的异常...。”。我使用了依赖项遍历器来查找任何缺少的依赖项,但找不到任何可能的原因,因为我试图在主代码中手动加载dll。

AlexF提到的链接中的答案之一解决了我的问题。(https://stackoverflow.com/a/31723080/5484662

我首先在configurationProperties-> Debugging中将“调试器类型”更改为“混合”模式。这导致了更详细的错误,该错误清楚地提到了缺少哪个依赖项。然后将依赖关系复制到Debug文件夹中,并且可以正常工作。