[Mono-devel-list] Interop with unmanaged code without copyingor memory allocation?

Karl Waclawek karl at waclawek.net
Tue Jan 13 00:10:30 EST 2004


> It sounds like you're trying to wrap a difficult API.  Good luck.

Thanks. ;-) Did it with Delphi. Hope it isn't much more difficult with C#.
 
> Regarding Problem 1 (interning strings), is there any particular reason
> you want the strings interned?  The only time it's useful is if you want
> to use pointer comparison instead of string comparison for strings,
> which would require that users do this:
> 
> ((object) String1) == ((object) String2)
> 
> I suspect most people will stick with the typical:
> 
> String1 == String2
> 
> which calls Object.Equals, so there's no reason to intern the string
> (unless you want to require your users use the first code).

The reason is that in a typical case the XML parser will report
the same name over and over again. Rather than allocating the
same string over and over I would prefer to look it up
in the pool. I did the same with Delphi and it seems to be
beneficial, resource and performance wise. Memory allocation
is expensive.
 
> Assuming you do want to intern the string, you could create a hashtable,
> manually hash the "const XML_Char *name", and use this hash value to
> lookup the interned string.  This would likely require writing your own
> hash function (so it can operate on a "const XML_Char*"), and you'd have
> to consider hash table conflicts, but this could be made to work.

Yes - I have done this already with another wrapper (see above) - I was just
hoping I cold use the built-in string pool. Since this seems
rather impossible from what I see I will have to port the string
hash table to C#. 

> 
> Personally, I wouldn't worry about it until you've done the performance
> profiling (mono --profile is your friend!) and determined that string
> interning would actually be a benefit.

Yes, the question is: what works somewhere else may not work in C#.
However, it seems avoiding memory allocations is a good optimization
technique regardless of language (at least for the popular ones).

In the C/C++ world, Expat is used for high performance applications,
like parsing XML files in the giga-byte range. Maybe in the C# world
there is no audience for that. You are right, and if I had to write
all the wrapper code from scratch I would delay this to the end.
However, I think I can port most of it from Delphi, in the style
of a "re-write in spirit", not a straight copy. Will be a good
C# exercise.
 
> Regarding Problem 2, I can't think of any good way to avoid the
> marshaling/copying overhead.  Managed and unmanaged memory must be kept
> separate (to permit the use of non-conservative garbage collectors). 
> You could employ C# "unsafe" code in the callback methods, but this
> would prevent non-C# languages (VB, JavaScript, etc.) from being used as
> callbacks...

Yes, that is what I want to avoid.

One theoretical possibility is this: Expat allows you to pass it a set
of memory handlers (same signatures as the C runtime functions
malloc, realloc and free).
I could use this to force Expat to use "managed" memory which exists
as some byte array on the C# side. That way I could go from the
pointer passed in the call-back to the index in the array, without
having to copy. However, writing a memory allocator looks like
overkill and would probably cost more than it benefits.
 
> This is really the problem behind Problem 1 -- memory must be kept
> separate, and coming up with efficient ways to bridge the barrier is
> difficult, hence the marshaling overhead...
> 
>  - Jon


Thanks for your insights,

Karl 



More information about the Mono-devel-list mailing list