C# pinvoke free native c++ memory - c#

If i have a c++ function which returns a char* like this:
char *cctalk_app_event_name(DG_CCTALK_APP_EVT_CODE);
And the corresponding C# signature:
[System.Runtime.InteropServices.DllImportAttribute("cctalk.dll", EntryPoint = "cctalk_app_event_name", CallingConvention = CallingConvention.Cdecl)]
public static extern System.IntPtr cctalk_app_event_name(DG_CCTALK_APP_EVT_CODE param0);
If the native code returns a char* allocated with the new keyword, i am for sure gonna have a memleak each time i call this function C#? Is there a way i can free that memory?

My hunch from looking at the function name is that this may well be returning a pointer to a string constant within the DLL, in which case you don't need to worry about freeing the pointer anyway.
If the manual for the SDK (link here) wasn't any use, then I'd disassemble the DLL and look at what that function did, but don't worry about how to delete it before you've established that you need to.

If you don't have any documentation or source then you cannot know whether or not the memory was allocated with new. If it was allocated with new then it needs to be deallocated with delete. That can only be done from the native code. If that is needed then the DLL will need to export a deallocator for you.
Other possibilities include allocation from a shared heap, e.g. the COM heap. Not very likely. Or perhaps the string is statically allocated and does not need deallocation. This final option is usually the case when a functions returns a C string as a return value. If you had to guess, that's the percentage option. In any case, if there's no way for you to deallocate the string, what else can you do?
The only way you can be sure is to have documentation, or source code, or support from the author. I appreciate that you want to know the solution, but your only hope are the options listed in the first sentence of this paragraph.
I find it hard to believe that a library this complex has no documentation. How did you come by this library? Are you really sure there are no docs?

Related

`fixed` vs GCHandle.Alloc(obj, GCHandleType.Pinned)

I tried to find out how pinned pointers defined with fixed keyword work. My idea was that internally GCHandle.Alloc(object, GCHandleType.Pinned) was used for that. But when I looked into the IL generated for the following C# code:
unsafe static void f1()
{
var arr = new MyObject[10];
fixed(MyObject * aptr = &arr[0])
{
Console.WriteLine(*aptr);
}
}
I couldn't find any traces of GCHandle.
The only hint I saw that the pinned pointer was used in the method was the following IL declaration:
.locals init ([0] valuetype TestPointerPinning.MyObject[] arr,
[1] valuetype TestPointerPinning.MyObject& pinned aptr)
So the pointer was declared as pinned, and that did not require any additional methods calls, to pin it.
My questions are
Is there any difference between using pinned pointers in the declaration and pinning the pointer by using GCHandle class?
Is there any way to declare a pinned pointer in C# without using fixed keyword? I need this to pin a bunch of pointers within a loop and there's no way I can do this using fixed keyword.
Well, sure there's a difference, you saw it. The CLR supports more than one way to pin an object. Only the GCHandleType.Pinned method is directly exposed to user code. But there are others, like "async pinned handles", a feature that keeps I/O buffers pinned while a driver performs an overlapped I/O operation. And the one that the fixed keyword uses, it doesn't use an explicit handle or method call at all. These extra ways were added to make unpinning the objects again as quick and reliable as possible, very important to GC health.
Fixed buffer pins are implemented by the jitter. Which performs two important jobs when it translates MSIL to machine code, the highly visible one is the machine code itself, you can easily see it with the debugger. But it also generates a data structure used by the garbage collector, completely invisible in the debugger. Required by the GC to reliably find object references back that are stored in the stack frame or a CPU register. More about that data structure in this answer.
The jitter uses the [pinned] attribute on the variable declaration in the metadata to set a bit in that data structure, indicating that the object that's referenced by the variable is temporarily pinned. The GC sees this and knows to not move the object. Very efficient because it doesn't require an explicit method call to allocate the handle and doesn't require any storage.
But no, these tricks are not available otherwise to C# code, you really do need to use the fixed keyword in your code. Or GCHandle.Alloc(). If you are finding yourself getting lost in the pins then high odds that you ought to be considering pinvoke or C++/CLI so you can easily call native code. The temporary pins that the pinvoke marshaller uses to keep objects stable while the native code is running are another example of automatic pinning that doesn't require explicit code.

C++ DLL crashes when calling from managed code

there's a WinForms-application written in C# using .NET Framework 3.5. This application uses a C++ Dll which is imported using the following declaration:
[DllImport(DllName)]
public static unsafe extern int LoadDBData(String dsn, String userid, String password);
This method imports data from a given ODBC-DSN using a SQL Server database. The call crashes when there is too much data in database. The provider of this extern dll said this happens because the dll is unable to grab more heap size and my application should provide more heap memory.
How could I solve this problem? As far as I know the only possibility to exclude a component from automatic garbage collection is the unsafe keyword which I already used.
Any idea would be appreciated.
Thanks in advance
Martin
This seems like a problem with the vendor's library, rather than your code.
Managed and unmanaged memory should be considered to be completely separate. Managed memory is typically memory allocated on a garbage-collected
heap, while unmanaged memory is anything else: the ANSI C memory pool
allocated through malloc(3), custom memory pools, and
garbage-allocated heaps outside the control of the CLI implementation...
Note that the above quote is from the Mono documentation, but I believe (if I'm not mistaken) the same is true for .NET in general. If the data is being loaded in the DLL's internal data structures, then it should allocate its own memory. If you're providing a buffer which will get filled up with the data, then it will only get filled up with as much data as you've allocated for the buffer (and pinned before marshalling). So where is the data being loaded?
You can't increase the heap size in .NET.
You could create an EXE in c/c++ that your .NET app calls using Process.Start.
Your c/c++ EXE would just call the DLL function and return the result (or if you have more than one function it could take a command line parameter). If you don't want a separate EXE you could try using RunDll32 instead.
I doubt this is specific to .NET, managed memory, garbage collection etc. It's a native DLL so it uses regular, unmanaged memory. Of course, the .NET runtime will also use it's share of memory but a native application using the DLL would do the same.
If you're running in a 32 bit process, the total heap size for .NET and unmanaged code can be limited to 1.5 GB. It's difficult to tell without additional information, but you might have hit that limit.
So one option would be to ask your vendor, whether they have a 64 bit version of the library and switch to a 64 process. In a 64 bit process, memory is almost unlimited (according to today's standard).

Performance of Calling Unmanaged .dll from C#

How long is the typical overhead added by calling a .dll written in C++ from a C# application using the following syntax?
[DllImport("abc.dll", EntryPoint = "xcFoo", CallingConvention = CallingConvention.Cdecl)]
public extern static Result Foo(out IntPtr session,
[MarshalAs(UnmanagedType.FunctionPtr)]ObjectCallback callback,
UInt64 turnKey,
string serverAddress,
string userId,
string password);
Is there a more efficient way to do it?
Check out this article on how to improve interop performance. What to do and what best to avoid.
http://msdn.microsoft.com/en-us/library/ms998551.aspx
Are you talking about the overhead of invoking the native method? If so, I dont think it is significant at all, as there are a lot of such calls in the .NET framework class libraries.
Now, whether the overhead is significant for your scenario can only be answered by doing performance measurements, and comparing them against what you expect.
The marshalling into the native method will cost three memory allocations from the NT heap, which is not so bad. It's the delegate back that gets worrysome.
A good method to check this sort of thing is throw in a break point where you make calls. Don't know when the library is loaded, so maybe only check the break point on the second call (unless loading cost is your main concern). Then open up the disassembly window in visual studio and see how many lines there are before your dll function is being invoked.
i know this question is old but ive managed to call native functions blazingly fast with not only using calli CIL instruction but also with special trick, but ofc you need to handle pinnig and/or marshalling arguments yourself if you deal with complex types including strings..

How to send unmanaged function pointers from dll to another unmanaged function in other dll through managed code?

I have this problem, which I am dealing with for some time already. At start, I have two dlls with unmanaged code (let's say... dll_1, dll_2) and managed aplication in c#. What i'm supposed to do is to get pointers to unmanaged functions in dll_1 in managed code, pack it into structure, and send this structure as an argument to unmanaged function in dll_2. Have anyone dealt with that kind of problem before maybe?
Since you don't do anything in managed code but the DLLs live in the same process, just use an IntPtr (is automatically 32 or 64 bits depending on the platform) to pass the unmanaged pointer around. You can of course also insert the IntPtr into your struct and use it as argument or return value when using an external call (e.g. [DllImport('YourDll')] static extern IntPtr ImportedFunction();).
However, to give you more information, it would be necessary to know more about the DLL calls and their data structures.

When passing a managed byte[] array through PInvoke to be filled in by Win32, does it need to be pinned?

Suppose you're calling a Win32 function that will fill in your byte array. You create an array of size 32, empty. Then pass it in to the Win32 function to be filled int, and use it later in your managed code. Does there exist the chance that the byte array might be moved or overwritten in between the time it was allocated and it is filled in by the Win32 function?
Short Answer: No, pinning is not necessary in this case
Longer Answer:
The CLR will automatically pin references to managed objects when they cross the PInvoke boundary. As soon as the PInvoke function exits the reference will be unpinned. So in situations like having a native function fill a byte[] no manually pinning is necessary because the object is only used by native code during the function call.
Manually pinning of the array becomes necessary if the native code caches the managed pointer. When this happens you must manually pin the array until the native code no longer needs the pointer. In this case I presume the pointer is not cached hence it's not necessary to pin
Reference - http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2
according to msdn Marshaling Arrays of Types only an array passed by reference can be written to by unmanaged code. So it appears that you must declare the array parameter [out] or [in,out] if you want to fill it in on the unmanaged side.
This page http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspx manages to go on and on without ever explicitly saying that the marshaller pins the arrays during the call from managed to unmanaged, but much of what it describes wouldn't work if the marshaller didn't pin.
Sorry to answer my own question but I believe if the type is blittable, as byte[] is, then the array would be pinned while being marshalled by the runtime, so no pinning would be needed. An object on the other time would be different. Please correct me if I'm wrong.

Categories

Resources