how to unload a dll to release memory in vb.net with cf?

S

sheng shan

Hi everyone,
I built a dll which access physical memory in platform builder
4.2,now when I use it in a timer in vb.net with cf,I found it create a
memory leak,my program is like this:
first I declare it in a module:
......
<System.Runtime.InteropServices.DllImport("dualrama.dll",
CallingConvention:=Runtime.InteropServices.CallingConvention.Winapi,
SetLastError:=False)> Public Function ReadByte(ByVal VirtualAddr As
Integer, ByVal offset As Integer) As Byte
End Function
<System.Runtime.InteropServices.DllImport("dualrama.dll",
CallingConvention:=Runtime.InteropServices.CallingConvention.Winapi,
SetLastError:=False)> Public Sub WriteByte(ByVal VirtualAddr As Integer,
ByVal offset As Integer, ByVal myval As Byte)
End Sub
<System.Runtime.InteropServices.DllImport("dualrama.dll",
CallingConvention:=Runtime.InteropServices.CallingConvention.Winapi,
SetLastError:=False)> Public Sub ReadBlock(ByVal VirtualAddr As Integer,
ByVal offset As Integer, ByRef myval As Byte, ByVal mysize As Integer)
End Sub
......
then I call the functions in a timer of one form
......

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick

Call ReadBlock(VirtualAddr, Current_Baseaddr(4),
Data_Port4(0), 32)
Call ReadBlock(VirtualAddr, Current_Baseaddr(8),
Data_Port8(0), 32)
......
End Sub
...


the functions of the dll work just well,but the memory leak it created
crashed the system after the app running for about 2 hours.
I am trying figure out if it's possible to add some codes in the
timer_tick event to reload and unload the dll which may release the
memory the dll occupied,then the memory leak could be avoided.but how?
or I have to improve my dll code?but I check it again and again and
could find no problem.I would like to post the dll code if anybody is
interested in it.

Help please!
 
C

Chris Tacke, eMVP

How about adding a method to the DLL to release memory if you can't clean up
in the originally called method?

-Chris
 
S

sheng shan

Hi Chris,

Thank you for your reply.
So there's no way to unload the dll imported from the "originally
called method"?
below is the source code of the dll:


// DualRamA.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "DualRamA.h"
#include <pkfuncs.h>
#include <ceddk.h>

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}


/////////////////////////////////// Begin Function
//////////////////////////////////

ULONG WINAPI RamAMapAddress(ULONG PhyAddress)
{
unsigned char *DualRamVirtualAddr; // pointer to the base address
of Dual RAM
unsigned long VirtualAddr;
BOOL nTmpVal;

// SETUP DUAL RAM MEMORY MAPPED ADDRESS RANGE

DualRamVirtualAddr= (unsigned char *)VirtualAlloc(
0,
0x1000, // Reserve 4k of virtual address space
MEM_RESERVE,
PAGE_NOACCESS );

if (!DualRamVirtualAddr)
{
RETAILMSG(0, (TEXT("Virtual Address Allocation Failed")));
DWORD rtn = GetLastError();
return 0;
}

nTmpVal = VirtualCopy(
DualRamVirtualAddr,
(LPVOID)((PhyAddress<<4)/256),
0x1000,
PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);

RETAILMSG( 0,(TEXT("%X\n"),VirtualAddr));

if (nTmpVal != TRUE )
{
RETAILMSG(0, (TEXT("VirtualCopy Failed")));
DWORD rtn = GetLastError();
return 0;
}

VirtualAddr=(unsigned long)DualRamVirtualAddr;
// free(DualRamVirtualAddr);
DualRamVirtualAddr=NULL;
return VirtualAddr;
}


UCHAR WINAPI ReadByte(ULONG VirtualAddr,ULONG Offset)
{

UCHAR Buffer;
PUCHAR DPRamPtr;
malloc(8);
DPRamPtr=(unsigned char *)(VirtualAddr+Offset);
Buffer =*DPRamPtr;
// ForcePageout();
free(DPRamPtr);
DPRamPtr=NULL;
return Buffer;
}

// Write a byte into the Buffer
DWORD WINAPI WriteByte(ULONG VirtualAddr,ULONG Offset, UCHAR Buffer)
{
PUCHAR DPRamPtr;
malloc(8);
DPRamPtr=(unsigned char *)(VirtualAddr+Offset);
*DPRamPtr = Buffer;
// ForcePageout();
free(DPRamPtr);
DPRamPtr=NULL;
return 0;
}

// Read a Word into the Buffer
DWORD WINAPI ReadWord(ULONG VirtualAddr,ULONG Offset, PUCHAR Buffer)
{
PUCHAR DPRamPtr;
malloc(8);
DPRamPtr=(unsigned char *)(VirtualAddr+Offset);
memcpy(Buffer, DPRamPtr, 4);
free(DPRamPtr);
DPRamPtr=NULL;
return 0;
}

// Write a Word into the Buffer
DWORD WINAPI WriteWord(ULONG VirtualAddr,ULONG Offset, PUCHAR Buffer)
{
PUCHAR DPRamPtr;
malloc(8);
DPRamPtr=(unsigned char *)(VirtualAddr+Offset);
memcpy(DPRamPtr, Buffer, 4);
free(DPRamPtr);
DPRamPtr=NULL;
return 0;
}

// READ a Block into the Buffer
DWORD WINAPI ReadBlock(ULONG VirtualAddr,ULONG Offset, PUCHAR Buffer,
ULONG Size)
{
PUCHAR DPRamPtr;
malloc(64);
DPRamPtr=(unsigned char *)(VirtualAddr+Offset);
memcpy(Buffer, DPRamPtr, Size);
free(DPRamPtr);
DPRamPtr=NULL;
return 0;
}

// WRITE a Block into the Buffer
DWORD WINAPI WriteBlock(ULONG VirtualAddr,ULONG Offset, PUCHAR Buffer,
ULONG Size)
{
PUCHAR DPRamPtr;
malloc(64);
DPRamPtr=(unsigned char *)(VirtualAddr+Offset);
memcpy(DPRamPtr, Buffer, Size);
free(DPRamPtr);
DPRamPtr=NULL;
return 0;
}
DWORD WINAPI FreeMemory()
{

ForcePageout();
return 0;
}
//////////////////////////////////// End Functions
//////////////////////////////////


the RamAMapAddress function only be called once in an app to get the
actual address of the allocated memory.after actual address is passed to
other functions,
other functions can read&write the memory.
I could find no way to release the memory in my dll.

from my point,if the memory once allocated,its base address should be
stable.
any suggestion?
 
P

Paul G. Tobey [eMVP]

Wait a minute! You're calling free() on a calculated pointer in ReadByte()!
That can't be right.

Paul T.
 
S

sheng shan

I am afraid it's correct,in "readbyte" the free() function only release
a temporary pointer(which passed a desired value before released),not
the real one.and the "readbyte" is tested by my app,it just work
well.the only problem is the memory leak the loaded dll will creates.
thanks!
 
S

sheng shan

I searched MSDN,find the functions:
ForcePageout
PageOutModule
maybe I can use them to solve the memory leak?
but how to use them in vb.net with cf?
any professinals please help!
 
P

Paul G. Tobey [eMVP]

I've never used either of those functions and would be surprised if that's
the problem.

I still think that your call to free() is wrong. Free() is the C run-time
library 'free', right? Well, the only pointers you can pass to that are
those allocated with malloc(). You're trying to tell me that you
malloc()-ed memory at an offset from some other allocated pointer? I doubt
that.

Paul T.
 
P

Paul G. Tobey [eMVP]

You didn't send all of the code necessary to do that, but I'm virtually
certain that the leak is of the memory which you allocated with malloc(8) in
the read byte and write byte routines (which are set up in a very
unintuitive way; you don't have to do all that junk!). I've done tons of
physical memory access and there are no leaks unless your code creates them.
Try removing those malloc() calls and I bet that most of your problems go
away (the free() call is also wrong, but it probably just corrupts memory,
not leaking it).

Paul T.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top