C#调用基于C ++单例类的dll

时间:2014-09-05 19:03:45

标签: c# c++ dll marshalling

我试图从C#调用C ++ dll。

C ++ dll是一个单例类,如下所示: .h文件(简化)

#if defined(STATS_MANAGER)
#define DllExport_StatsManager __declspec(dllexport)
#else
//    definitions used when using DLL
#define DllExport_StatsManager __declspec(dllimport)
#endif    

#pragma warning( push )
#pragma warning( disable : 4251 )

class DllExport_StatsManager StatsManager
{
private:    
    StatsManager();
    static auto_ptr<StatsManager> _single;

public:
    ~StatsManager();
    static StatsManager* getInstance();
    void SetMaskPtr(unsigned short* maskPtr);

};

.cpp文件(简化)

#include "stdafx.h"
#include "StatsManager.h"
#include "ImageStats.h"

auto_ptr<LogDll> logDll(new LogDll(L".MyLoggingUnmanaged.dll"));
wchar_t message[256];

typedef void (_cdecl *statsPrototype)(long chan, long &numROI, long * min, long *max, double *mean, double *stdDev);

void (*statsFunctionPointer)(long chan, long &numROI, long * min, long *max, double *mean, double *stdDev) = NULL;

bool StatsManager::_instanceFlag = false;

bool StatsManager::_setupFlag = false;

StatsManager::StatsManager()
{
    SetThreadBusyStatus(FALSE);
    SetDataPtr(NULL);
    SetMaskPtr(NULL);
    hThread = NULL;
}

StatsManager::~StatsManager()
{
    _instanceFlag = false;
}

auto_ptr<StatsManager> StatsManager::_single(new StatsManager());

StatsManager* StatsManager::getInstance()
{
    if(! _instanceFlag)
    {
        try
        {
            _single.reset(new StatsManager());

            wsprintf(message,L"StatsManager Created");
            logDll->TLTraceEvent(VERBOSE_EVENT,1,message);
        }
        catch(...)
        {
            //critically low on resources
            //do not proceed with application
            throw;
        }
        _instanceFlag = true;
        return _single.get();
    }
    else
    {
        return _single.get();
    }
}

//model will call this function
long StatsManager::SetStatsMask(unsigned short *mask, long width, long height)
{
    long ret = TRUE;

    realloc(StatsManager::getInstance()->GetMaskPtr(),width*height*sizeof(unsigned short));
    memcpy(mask,StatsManager::getInstance()->GetMaskPtr(),width*height*sizeof(unsigned short));

    return ret;
}

在我的C#代码中,我想调用SetStatsMask(unsigned short *mask, long width, long height),但它会抛出异常&#34; 无法找到入口点&#39; SetStatsMask&#39;在StatsManager.dll &#34;。这是我的C#代码:

[DllImport("StatsManager.dll", EntryPoint = "SetStatsMask")]
private static extern int SetStatsMask(IntPtr mask, int imgWidth, int imgHeight);

try
{
    ea.Result = mask;
    IntPtr maskPtr = Marshal.AllocHGlobal(2 * mask.Length);
    Marshal.Copy(mask, 0, maskPtr, mask.Length);
    SetStatsMask(maskPtr, width, height);
    SaveMask("d:\\myMask.csv", mask);
}
catch (Exception e)
{
    e.ToString();

}  

我相信我的C ++ DLL路径是对的,所以此时我不确定导致此问题的原因。有人可以给点指点吗?非常感激。感谢。

1 个答案:

答案 0 :(得分:1)

编译器找不到SetStatsMask(),因为它正在寻找一个类外的函数。您无法使用DllImport来调用c ++类&#39;以这种方式运作。

我打算建议在StatsManager类之外创建一个函数来调用它,但看起来你的SetStatsMask()成员函数不需要StatsManager成员函数的任何非公开部分{1}},你可以把它变成一个普通的函数而不是一个成员函数,并且很好。

long SetStatsMask(unsigned short *mask, long width, long height)
{
    long ret = TRUE;

    realloc(StatsManager::getInstance()->GetMaskPtr(),width*height*sizeof(unsigned short));
    memcpy(mask,StatsManager::getInstance()->GetMaskPtr(),width*height*sizeof(unsigned short));

    return ret;
}