I am trying to call from C# to C++ dll.
The C++ dll is a singleton class like following: .h file (simplified)
#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 file (simplified)
#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;
}
In my C# code, I want to call SetStatsMask(unsigned short *mask, long width, long height)
, but it throws exception " cannot find entry point 'SetStatsMask' in StatsManager.dll ". Here is my C# code:
[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();
}
My C++ dll path I believe is right, so at this point I am not sure what causes this problem. Anyone can kindly give some pointers? Very appreciated. Thanks.
The compiler cannot find SetStatsMask()
because it is looking for a function that is outside of a class. You cannot use DllImport
to call the c++ class' function in this way.
I was going to recommend creating a function outside of the StatsManager
class to call into it, but it looks like your SetStatsMask()
member function doesn't need any non-public portions of StatsManager
, and you could just turn it into a regular function instead of a member function and be good to go.
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.