How do you prevent garbage collection?

C

Chris

Hi,

I think I'm having some problems here with garbage collection. Currently, I
have the following code:

public struct Event

{

public int timestamp;

public EventType event;

public short device;

public int status;

public int input;

}

and the following method using the above struct:

unsafe private void Message( int msg )

{

Event myEvent = new Event();

while ( GetEvent(myEvent) != -1 )

{

// do some work

}

}

GetEvent is a call to an external DLL written in C++. When I send the
myEvent reference to the DLL, I receive a 'System.NullReferenceException'.
I believe this is because that myEvent gets garbage collected shortly after
the function call to the dll. Am I correct? How do I prevent the struct
(or reference to the struct) from being garbage collected until after the
function call is complete?

Thanks in advance,

Chris
 
S

Sridhar Panatula

Hello Chirs,

I too do not think that, what you are seeing is because of Garbage
Collection.
The easiest way to check whether your Object has been removed or not is to
print values after the Call to DLL.

But, I think its due to the nature of the two different platforms(if I can
call .NET as platform).
When you create an object in .NET its part of the managed application. So I
do not think you can pass the reference to Unamanaged app to use that memory
address.
Firstly it may not be the true address and secondly the values stored may
not be similar to how values are stored in a plain C++/VB/Windows app. For
example in remoting the objects are transported by Boxing/Unboxing and
similar should happen in your case.

So you should be looking at "How to pass values between managed and
Unmanaged applications"

One somewhat relevant I could find quikcly is
http://msdn.microsoft.com/netframew...=/library/en-us/dndotnet/html/callcomcomp.asp

I am not sure that the above can answer all your questions but I hope it
puts on the right path to solving the issue.

If you still think it is because of the GC the easy way to prevent GC is by
having a reference to that Object
and not release until you are done calling your external(unamanged ) app.


Good luck
Sridhar
 
C

Chris

Hi Sridhar,

Thanks for your comments. I'm on my way to research some of the avenues
that you've opened up for me. I'm not necessarily convinced that the
problem is related to garbage collection either. At the time, I just
thought it might be a possibility, hence the statement "Am I correct?"
Nonetheless, we'll see what else I can turn up.

Later on, I may test the GC avenue anyway just to learn a little bit more.
Do you have an example of how I could create a reference to the
object/struct? I haven't been able to find one.

Thanks!

Chris
 
C

Chris

Hi Nicholas,

I hope this is what you mean:

====================================
Enumerators and Structures:

public enum EventType
{
evtState,
evtMesg,
evtTrans
}

public struct Event
{
public int timestamp;
public EventType event;
public short device;
public int status;
public int inputid;

public Event( int timestamp, EventType event, short device, int status,
int inputid )
{
this.timestamp = timestamp;
this.event = event;
this.device = device;
this.status = status;
this.inputid = inputid;
}
}
====================================
DriverUnit.cs:

public class DriverUnit
{
unsafe private void Message ( int msg )
{
Event myEvent = new Event();

while ( Get Event (myEvent) != 1 )
{
// do work
}
}

[DllImport("rDriver.dll", CharSet=CharSet.Auto)]
private static extern int GetEvent ( Event pEvent );
}

====================================
rDriver.cpp:


long GetEvent ( Event* pEvent )
{
dManager* pManager = dManager::GetInstance();
if ( pManager )
{
return pManager->GetEvent2( pEvent );
}
else
{
return -1;
}
}

====================================

long GetEvent2 (Event* pEvent)
{
return itsEventQueue.Remove( pEvent )
}

====================================

int virtualQueue<T>::Remove ( T* element )
{
// itsRemovePoint contains data retrived from hardware in the format of
struct type 'Event'

*element = *itsRemovePoint;

... // continue running code

// I get a 'System.NullReferenceException' at the above line
}
====================================

Notes:

The following is the process flow:

In 'Message' function of DriverUnit.cs a struct of type Event is created.
It is then passed through the DLLImport interface to the 'GetEvent' method
that resides in rDriver.cpp which is part of the rDriver.dll. When
'GetEvent' is run, the value of the pointer 'pEvent' is 0x00000000.
Eventually, 'Remove' is called which removes data retrieved from hardware
and assigns it to the location of element. However, I receive a
'System.NullReferenceException' when this line of code is run.

Thanks for your help,

Chris


Nicholas Paldino said:
Chris,

Can you post the definition of the structure and the functions that you
are passing the structure to? This would help immensely.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Chris said:
Hi,

I think I'm having some problems here with garbage collection.
Currently,
I
have the following code:

public struct Event

{

public int timestamp;

public EventType event;

public short device;

public int status;

public int input;

}

and the following method using the above struct:

unsafe private void Message( int msg )

{

Event myEvent = new Event();

while ( GetEvent(myEvent) != -1 )

{

// do some work

}

}

GetEvent is a call to an external DLL written in C++. When I send the
myEvent reference to the DLL, I receive a 'System.NullReferenceException'.
I believe this is because that myEvent gets garbage collected shortly after
the function call to the dll. Am I correct? How do I prevent the struct
(or reference to the struct) from being garbage collected until after the
function call is complete?

Thanks in advance,

Chris
 
C

Chris

Hmm ... how incredibly dumb of me ... thanks for your suggestion - it seems
to be working now!

Thanks,

Chris


100 said:
Hi Chris,
The problem is not in the GC. As long as it is a struct (value type) the
operator new creates the object as a vlaue-type object in the stack and its
memory becomes free as soon as the method ends. I has nothing to do with the
GC. The problem, I thing, is in the way you have declared the external
method for the GetEvent function.
As I can see form the next messages on the thread the c++ prototype is
long GetEvent (Event* pEvent );
As long as Event is a value type and the GetEvent wants the addres you
should consider using the following declaration

[DllImport("dll-name")]
public static extern Int32 GetEvent(ref Event pEvent) ;

and calling it as:
while ( GetEvent(ref myEvent) != -1 )
{

}

HTH
B\rgds
100
Chris said:
Hi,

I think I'm having some problems here with garbage collection.
Currently,
I
have the following code:

public struct Event

{

public int timestamp;

public EventType event;

public short device;

public int status;

public int input;

}

and the following method using the above struct:

unsafe private void Message( int msg )

{

Event myEvent = new Event();

while ( GetEvent(myEvent) != -1 )

{

// do some work

}

}

GetEvent is a call to an external DLL written in C++. When I send the
myEvent reference to the DLL, I receive a 'System.NullReferenceException'.
I believe this is because that myEvent gets garbage collected shortly after
the function call to the dll. Am I correct? How do I prevent the struct
(or reference to the struct) from being garbage collected until after the
function call is complete?

Thanks in advance,

Chris
 

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