2014-09-05 55 views
0

我想從C#調用到C++的DLL。C#調用C++單例類基於DLL

C++的DLL是一個單例類似如下:(簡體)

#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#代碼,我想打電話給 .h文件中SetStatsMask(unsigned short *mask, long width, long height),但它拋出異常「找不到入口點」StatsManager.dll「中的SetStatsMask」。這裏是我的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

編譯器找不到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; 
} 
+0

這是有效的。完善!謝謝。 – Ono 2014-09-05 20:52:08