P/Invoke for void **

D

Dilip Krishnan

Hi I'm having a function in a Dll that has the following signature.

int foo(void **ppSomeHandle, char *str1, char* str2)

I was wondering whats the best way to access it in managed code. In C#
how would I define the same

[DllImport....]
public static extern unsafe int foo(IntPtr *ppSomeHandle, string str1,
string str2);


OR

[DllImport....]
public static extern int foo(ref IntPtr pSomeHandle, string str1, string
str2);

My main concerns are around the ppSomeHandle parameter. Is the second
option even possible? I was wondering if anyone in the group had some
experience in the calling unmanaged dll functions.

Also just to clarify the intent of the dll function. Its used to
retreive a handle and the assumption is that the function will
initialize the pointer and populate the handle value.

Thanks for your help
 
N

Nicholas Paldino [.NET/C# MVP]

Dilip,

As a matter of fact, both are correct. The second declaration is
correct, and you don't need rights to run unsafe code to do it. The ref
keyword will allow the contents of that IntPtr (which is already a pointer)
to be changed, acting like a double pointer.

Hope this helps.
 
D

Dilip Krishnan

Nicholas,
Yes, but I'm also interested in the garbage collection and memory
locations depency around that parameter. What are the implications of
having a parameter in managed code whose allocation has occured in the
unmanaged world? And would I need to free this reference, My main
concern is to avoid leaking memory.
Since this piece is a reusable piece of code and will be used
frequently by other applications, I'm concerned with the bubble effect
of the memory leak over time.
Thanks
 
N

Nicholas Paldino [.NET/C# MVP]

Dilip,

Of course you have to release the memory that is allocated by this
function.

Garbage collection isn't going to touch this memory. You have to be
responsible for freeing it. What you want to do is on return, you want to
convert whatever the pointer is into a managed format. Once you have that,
you need to free the memory. This requires you to know how the memory was
allocated, so that you may free it correctly. Generally speaking, functions
like this are dangerous, because they tie you into a particular memory
allocation scheme (new, malloc, CoTaskMemAlloc, GlobalAlloc, etc, etc). It
would be better if the function took a pointer and the length of the buffer
pointed to by the pointer, and then wrote to that address in memory. That
way, the memory management is left to the caller, as is the deallocation of
the memory.

When you know how the memory is allocated, you have to use the correct
call to free it (delete, free (both not possible in .NET, you have to write
another function which will release the memory), CoTaskMemFree, GlobalFree,
etc, etc).
 
D

Dilip Krishnan

Was really concerned about going that route :( Especially since I have
no knowledge of the implementation, As far as I'm concerned the DLL is a
blackbox. So I wouldnt know how that memory got allocated, I dont even
know what kind of an object it is! I'd have to assume an integer handle
of some sort. Any idea what I'd do in such a scenario?
 
N

Nicholas Paldino [.NET/C# MVP]

Dilip,

In that case, you really have a problem. If you don't know what is
allocating the memory internally, then you can't be sure of how to
deallocate that memory outside of the function. You will have to contact
the provider, or find documentation indicating how it is done.

If you don't have access to that, then you will have to run some sort of
memory profiler, and try all sorts of different de-allocation routes. The
first I would try is free, then delete, then GlobalFree, then CoTaskMemFree.
Once you find out which one works, create another unmanaged piece of code
that will take a buffer that is allocated by the caller, not by the system.
 

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