Memory overflow when using a CLR DLL

  • Thread starter Thread starter r2du-soft
  • Start date Start date
R

r2du-soft

Guest
Hello

i using from a dll written with CLR

when i use that ,for each call to that dll,my application usage more memory and in many hours the all of memory Occupied.

I'm not familiar with CLR language

The codes are as follows:

exdll.h:

#ifndef _EXDLL_H_
#define _EXDLL_H_

#include <windows.h>

#if defined(__GNUC__)
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif

// only include this file from one place in your DLL.
// (it is all static, if you use it in two places it will fail)

#define EXDLL_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }

// For page showing plug-ins
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
#define NOTIFY_BYE_BYE 'x'

typedef struct _stack_t {
struct _stack_t *next;
char text[1]; // this should be the length of string_size
} stack_t;


static unsigned int g_stringsize;
static stack_t **g_stacktop;
static char *g_variables;

static int popstring(char *str) UNUSED; // 0 on success, 1 on empty stack
static void pushstring(const char *str) UNUSED;
static char * getuservariable(const int varnum) UNUSED;
static void setuservariable(const int varnum, const char *var) UNUSED;

enum
{
INST_0, // $0
INST_1, // $1
INST_2, // $2
INST_3, // $3
INST_4, // $4
INST_5, // $5
INST_6, // $6
INST_7, // $7
INST_8, // $8
INST_9, // $9
INST_R0, // $R0
INST_R1, // $R1
INST_R2, // $R2
INST_R3, // $R3
INST_R4, // $R4
INST_R5, // $R5
INST_R6, // $R6
INST_R7, // $R7
INST_R8, // $R8
INST_R9, // $R9
INST_CMDLINE, // $CMDLINE
INST_INSTDIR, // $INSTDIR
INST_OUTDIR, // $OUTDIR
INST_EXEDIR, // $EXEDIR
INST_LANG, // $LANGUAGE
__INST_LAST
};

typedef struct {
int autoclose;
int all_user_var;
int exec_error;
int abort;
int exec_reboot;
int reboot_called;
int XXX_cur_insttype; // deprecated
int XXX_insttype_changed; // deprecated
int silent;
int instdir_error;
int rtl;
int errlvl;
int alter_reg_view;
int status_update;
} exec_flags_type;

typedef struct {
exec_flags_type *exec_flags;
int (*ExecuteCodeSegment)(int, HWND);
void (*validate_filename)(char *);
} extra_parameters;

// utility functions (not required but often useful)
static int popstring(char *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
lstrcpyA(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}

static void pushstring(const char *str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
lstrcpynA(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}

static char * getuservariable(const int varnum)
{
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
return g_variables+varnum*g_stringsize;
}

static void setuservariable(const int varnum, const char *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
lstrcpyA(g_variables + varnum*g_stringsize, var);
}



#endif//_EXDLL_H_


NSIS_CLR_Loader.cpp:


#include "exdll.h"
#include <string>
#include <vector>
using namespace std;
using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Reflection;

HINSTANCE g_hInstance;
HWND g_hwndParent;

System::Reflection::Assembly ^ LoadAssembly(String ^filename)
{
Assembly ^assembly = nullptr;
FileStream ^fs = File::Open(filename, FileMode::Open);
if (fs != nullptr)
{
MemoryStream ^ms = gcnew MemoryStream();
if (ms != nullptr)
{
cli::array<unsigned char> ^buffer = gcnew cli::array<unsigned char>(1024);
int read = 0;
while ((read = fs->Read(buffer, 0, 1024))>0)
ms->Write(buffer, 0, read);
assembly = Assembly::Load(ms->ToArray());
ms->Close();
delete ms;
}
fs->Close();
delete fs;
}

return assembly;

//http://forums.msdn.microsoft.com/en-US/clr/thread/093c3606-e68e-46f4-98a1-f2396d3f88ca/
}

char* CallCLR(string DllName, string ClassWithNamespace, string MethodName, vector<string> Args)
{
try
{
// get DLLName, Namespace, Class and Method
String ^sDLLName = (gcnew String(DllName.c_str()))->Trim();
if (!sDLLName->ToLower()->EndsWith(".dll"))
sDLLName += ".dll";
String ^sClassWithNamespace = (gcnew String(ClassWithNamespace.c_str()))->Trim();
String ^sMethod = (gcnew String(MethodName.c_str()))->Trim();

// load assembly (is closed on disk right away)
System::Reflection::Assembly ^assembly = LoadAssembly(".\\" + sDLLName);
if (assembly == nullptr)
throw gcnew Exception("Error loading .NET assembly");

// attempt to find the class
bool found = false;
cli::array<Type ^> ^types = assembly->GetExportedTypes();
for (int i=0; i<types->Length; i++)
{
if (types->FullName == sClassWithNamespace)
{
found = true;

// found the class, create instance, get methodinfo and parameter info
System::Object ^instance = assembly->CreateInstance(sClassWithNamespace);
System::Reflection::MethodInfo ^methodinfo = instance->GetType()->GetMethod(sMethod);
if (methodinfo == nullptr)
{
throw gcnew Exception(String::Format(
"Method {0} not found in class {1}",
sMethod, sClassWithNamespace));
}
cli::array<ParameterInfo ^> ^paraminfos = methodinfo->GetParameters();

// check that there are the same number of parameters in input and in dll to be called
if (Args.size() != paraminfos->Length)
{
throw gcnew Exception("Number of parameters does not match");
}

// create a new Object^ array with data types that
// corresponds to what the .NET method expects
cli::array<Object ^> ^params = gcnew cli::array<Object ^>(Args.size());
for (int i=0; i<(int)Args.size(); i++)
{
if (paraminfos->ParameterType->FullName == "System.String")
params = Convert::ToString(gcnew String(Args.c_str()));
else if (paraminfos->ParameterType->FullName == "System.Char")
params = Convert::ToChar(gcnew String(Args.c_str()));
else if (paraminfos->ParameterType->FullName == "System.Int32")
params = Convert::ToInt32(gcnew String(Args.c_str()));
else if (paraminfos->ParameterType->FullName == "System.Int64")
params = Convert::ToInt64(gcnew String(Args.c_str()));
else if (paraminfos->ParameterType->FullName == "System.Int16")
params = Convert::ToInt16(gcnew String(Args.c_str()));
else if ((paraminfos->ParameterType->FullName == "System.Double") ||
(paraminfos->ParameterType->FullName == "System.Float"))
params = Convert::ToDouble(gcnew String(Args.c_str()));
else if (paraminfos->ParameterType->FullName == "System.Boolean")
params = Convert::ToBoolean(gcnew String(Args.c_str()));
else if (paraminfos->ParameterType->FullName == "System.IntPtr")
params = gcnew System::IntPtr(Convert::ToInt32(gcnew String(Args.c_str())));
}

char* result;

// invoke method and return any value
System::Object ^retValue = methodinfo->Invoke(instance, params);
if (retValue != nullptr)
result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(retValue->ToString());
else
result = "";

// cleanup
DllName.clear();
ClassWithNamespace.clear();
MethodName.clear();
Args.clear();
delete sDLLName;
delete sClassWithNamespace;
delete sMethod;
delete params;
assembly = nullptr;
delete assembly;
delete instance;
delete methodinfo;
/*if (retValue != nullptr)
delete retValue;*/

return result;
}
}

if (!found)
{
throw gcnew Exception(String::Format(
"Class {0} not found in {1}",
sClassWithNamespace, sDLLName));
}

return "";
}
catch (System::Exception ^ex)
{
String ^msg = "Error calling .NET DLL method\n\n" + ex->Message;
Windows::Forms::MessageBox::Show(msg);
return "";
}
}

extern "C" __declspec(dllexport) void Call(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop,
extra_parameters *extra)
{
// expected parameters:
// filename.dll, namespace.namespace...class, method, numparams, params...

g_hwndParent=hwndParent;
EXDLL_INIT();

char buf[1024];

// filename.dll
popstring(buf);
string dllname = string(buf);

// namespace and class
popstring(buf);
string classwithnamespace = string(buf);

// method
popstring(buf);
string method = string(buf);

// num params
popstring(buf);
int numparams = atoi(buf);

// params
vector<string> args;
for (int i=0; i<numparams; i++)
{
popstring(buf);
string tmp = string(buf);
args.push_back(tmp);
}

char* result = (char*)CallCLR(dllname, classwithnamespace, method, args);
pushstring(result);
}

extern "C" __declspec(dllexport) void Destroy(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop,
extra_parameters *extra)
{
}

//#pragma unmanaged
//BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
//{
// g_hInstance=(HINSTANCE)hInst;
// return TRUE;
//}





what is the problem?

Continue reading...
 
Back
Top