473,325 Members | 2,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

Garbage collection and callbacks from unmanaged code.

Hello, all,

I have a .NET application (VB) that passes the address of a delegate to
unmanaged code in a DLL. The unmanaged code then uses the delegate as a
call-back.

This seems to work fine, but now I am worried about garbage collection.
I am concerned that the location of the delegate might be altered as
a result of other (unused) objects being garbage collected. This would
probably cause undesirable results when the unmanaged DLL attempted to
make a subsequent call-back operation.

Although I haven't yet seen such a problem, I understand that garbage
collection is largely uncontrollable and unpredictable. So I am worried
about mysterious and sporadic problems appearing when the application is
actually in use. To avoid this possibility, I tried "pinning" the
delegate, but I get the error message:

"Object contains non-primitive or non-blittable data."

Are my concerns about this justified? If so, what (if anything) can I
do to prevent this problem?

For any who are interested, I have posted relevant code snippets below.

Cheers,
Randy

Private Delegate Function mdgtDataInterface( _
ByVal strAction As String, _
ByVal intActionLen As Integer, _
<MarshalAs(UnmanagedType.SafeArray)> _
ByRef objaData() As Object) As aenmDataRequestStatus

...
...

' DataInterface is the .Net call-back routine.
Dim dgtDataInterface As mdgtDataInterface = AddressOf DataInterface
'''The following statement causes a System.ArgumentException.
'''Dim gchDIPin As GCHandle = GCHandle.Alloc(dgtDataInterface, _
GCHandleType.Pinned)
...

' This calls the unmanaged code and passes the call-back delegate.
Dim intStatus As Integer = RunUnmanaged(intModelAddress, _
dgtDataInterface, _
strMessage)
...
...

' This is the call-back routine
Public Function DataInterface(ByVal strRequest As String, _
ByVal intRequestLength As Integer, _
<MarshalAs(UnmanagedType.SafeArray)> _
ByRef objaData() As Object) _
As aenmDataRequestStatus
...
...

Mar 8 '06 #1
4 4963
Are my concerns about this justified? If so, what (if anything) can I
do to prevent this problem?


As long as you make sure the delegate itself doesn't get garbage
collected, you have nothing to worry about.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Mar 8 '06 #2
Hello, Mattias,

Thanks for the reassurance. A reference to the delegate is maintained
for the duration of the time that the unmanaged code is active, so there
is no worry about the delegate itself being garbage collected.

What worries me though, is the following quote from:
http://msdn2.microsoft.com/en-us/library/f144e03t.aspx

<quote>
During a collection, the garbage collector examines the managed heap,
looking for the blocks of address space occupied by unreachable objects.
As it discovers each unreachable object, it uses a memory-copying
function to compact the reachable objects in memory, freeing up the
blocks of address spaces allocated to unreachable objects. Once the
memory for the reachable objects has been compacted, the garbage
collector makes the necessary pointer corrections so that the
application's roots point to the objects in their new locations.
<end-quote>

This sounds to me like the memory location of the delegate is subject to
change. The unmanaged code (Fortran in this case) stores the address of
the delegate in an unmanaged integer variable that is not subject to
adjustment by the garbage collector.

So I have trouble understanding why I shouldn't worry. ;-)

I guess in addition to reassurance, I am also seeking enlightenment.

I can imagine a scheme whereby delegates are treated specially and never
moved as a result of garbage collection. Or I can imagine an
indirection scheme where delegates are always referenced through a fixed
pointer, and it is the address of this pointer that is passed to the
unmanaged code. Incidentally, I seem to have omitted the declaration of
"RunUnmanaged" in my previous post. It it:

Public Function RunUnmanaged(ByVal intFunctionPointer As Integer, _
ByVal dgtCallBackAddr As System.Delegate, _
<MarshalAs(UnmanagedType.BStr)> ByRef strMessage As String) _
As Integer

But these imagined schemes are just idle speculation on my part. The
best reassurance would come from my understanding of how this actually
operates. But, so far, I haven't been able to find any documentation
that makes this clear to me.

Can you point me towards the light?

Cheers,
Randy
Mattias Sjögren wrote:
Are my concerns about this justified? If so, what (if anything) can I
do to prevent this problem?

As long as you make sure the delegate itself doesn't get garbage
collected, you have nothing to worry about.
Mattias

Mar 8 '06 #3
>This sounds to me like the memory location of the delegate is subject to
change. The unmanaged code (Fortran in this case) stores the address of
the delegate in an unmanaged integer variable that is not subject to
adjustment by the garbage collector.

So I have trouble understanding why I shouldn't worry. ;-)


Just as you guessed yourself, the native code doesn't get a direct
pointer to the delegate but rather to some thunk code generated by the
marshaler. This indirection ensures that the native function pointer
remains valid even if the delegate is being moved.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Mar 9 '06 #4
Hello, Mattias,

Many thanks for that. My reassurance is now complete.

Do you know of a good reference where this whole area of "marshaling"
(and particularly interacting with unmanaged code) is documented in a
tutorial fashion. I have read the MS reference docs about this, but I
seem to be missing some of the basics and language required to
understand them. :-(

I have one other concern related to SafeArray interactions between
managed and unmanaged code that I will post as a new thread, but I
wouldn't mind being able to learn a little more about the whole area.

Again, thanks for your reply.

Cheers,
Randy
Mattias Sjögren wrote:
This sounds to me like the memory location of the delegate is subject to
change. The unmanaged code (Fortran in this case) stores the address of
the delegate in an unmanaged integer variable that is not subject to
adjustment by the garbage collector.

So I have trouble understanding why I shouldn't worry. ;-)

Just as you guessed yourself, the native code doesn't get a direct
pointer to the delegate but rather to some thunk code generated by the
marshaler. This indirection ensures that the native function pointer
remains valid even if the delegate is being moved.
Mattias

Mar 9 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: JC | last post by:
How does garbage collection work in C# and VB.NET for data returned from COM object? For example, a COM object written in C++ returns a SAFEARRAY to C# or VB.NET, will this SAFEARRAY (mapped to...
28
by: joe | last post by:
I have a simple .NET application with two or three listViews which are filled with icons and when the user click on the proper item, they display the related images. I use "image = null ; " for all...
14
by: Arvind | last post by:
hello ppl, i am trying to implement a garbage collector for c++ using the generational algorithm applying mark-sweep to each generation. i am unable to get any details about the algorithm. is it...
5
by: Bob lazarchik | last post by:
Hello: We are considering developing a time critical system in C#. Our tool used in Semiconductor production and we need to be able to take meaurements at precise 10.0 ms intervals( 1000...
3
by: John Sun | last post by:
Dear Group Gurus, If I use a COM class in my C# code, will the memory used by COM object be garbage collected, or do I have to manually collect it. Thanks, John
11
by: Fabien Penso | last post by:
Hi. I am trying to make this work but I got a weird behavior. I got a very basic system, I call a unmanaged "dllimported" function and give it a structure of callback functions. Sometimes,...
4
by: R. MacDonald | last post by:
Hello, all, I have a .NET application (VB) that passes the address of a delegate to unmanaged code in a DLL. The unmanaged code then uses the delegate as a call-back. This seems to work...
5
by: R. MacDonald | last post by:
Hello, all, I am currently working on a .Net (VB) application that invokes routines in unmanaged (Fortran) DLLs. The unmanaged routines then communicate with the .Net application by means of a...
56
by: Johnny E. Jensen | last post by:
Hellow I'am not sure what to think about the Garbage Collector. I have a Class OutlookObject, It have two private variables. Private Microsoft.Office.Interop.Outlook.Application _Application =...
6
by: Alan Mailer | last post by:
As an ex-VB6 person, I remember often having to make sure that my code set to "Nothing" objects I created throughout my programs. My cursory reading of some VB.Net info is that this may no longer...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.