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

C# calls C++ singleton class-based dll

本文关键字:单例类 dll C++ 调用      更新时间:2023-10-16

我正试图从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),但它抛出异常"在StatsManager.dll中找不到入口点"SetStatsMask""

[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路径是正确的,所以在这一点上我不确定是什么导致了这个问题。有人能提供一些建议吗?非常感谢。谢谢

编译器找不到SetStatsMask(),因为它正在查找类之外的函数。不能使用DllImport以这种方式调用c++类的函数。

我本来建议在StatsManager类之外创建一个函数来调用它,但看起来SetStatsMask()成员函数不需要StatsManager的任何非公共部分,您可以将它变成一个常规函数而不是成员函数,然后就可以了。

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