Unable to load function from c# dll using a c++/cli wrapper

1

This is my first time with calling functions from c# dlls.

I have made a c# wrapper(c++/cli) to call c# functions from c++. This wrapper itself is a dll which I want to use in my main code. Below are the wrapper.h and wrapper.cpp files. CSharpWrapper is the abstract class that inherits the base class ImageTool. At the end of the header file I am exporting a factory of the wrapper class.

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

In the wrapper.cpp file, visual studio is able to suggest the functions available in the c# dll. The following is the main.cpp code where I am trying to call functions through this wrapper.

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

Now, when I run main.cpp, it is able to create dll_imgcapture_handle and ImgFactory. But it gives the following error when instance_imgcapture->Initialize() is called:

Unhandled exception at 0x00007FFD20B5A388 (KernelBase.dll) in wrapper.exe: 0xE0434352 (parameters: 0xFFFFFFFF80070002, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x00007FFD03580000).

I tried this method to load dlls (as in main.cpp) with other c++ dlls - it works. I tried to check if there are any missing dlls using dependency_walker- there were none. I have included the correct opencv libraries and they work correctly. I have included the path to the dlls and libs in the project properties and added the lib names in Linker->Input.

Can you please help me to debug this problem.

c#
c++
dll
c++-cli
asked on Stack Overflow Jul 16, 2018 by Ankit • edited Jul 16, 2018 by Ankit

1 Answer

1

It was a mistake related to the dependencies. Since I am trying to call managed code from unmanaged, the output produced by the debugger does not clearly mention the error and just outputs "Unhandled exception at 0x00....". I used dependency walker to look for any missing dependencies but it cannot find anything probably because I am trying to load the dll manually in the main code.

One of the answers in the link mentioned by AlexF solved my problem.(https://stackoverflow.com/a/31723080/5484662)

I first changed the "Debugger Type" to "Mixed" mode in configurationProperties->Debugging. This resulted in a more detailed error which mentions clearly which dependency is missing. And I copied the dependencies in the Debug folder and it works.

answered on Stack Overflow Jul 16, 2018 by Ankit

User contributions licensed under CC BY-SA 3.0