all groups > dotnet interop > october 2006 >
You're in the

dotnet interop

group:

Memory error with funcs that return char*



Memory error with funcs that return char* Chuck C
10/30/2006 12:32:27 PM
dotnet interop: I have an odd error comming up that does not seem to actually cause a
problem (everything seems to work fine) but it concerns me.

Error:
----------------------------------------
HEAP[appname.exe]: Invalid Address specified to RtlFreeHeap( 00170000,
10015988 )
Windows has triggered a breakpoint in appname.exe.

This may be due to a corruption of the heap, and indicates a bug in
appname.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information
----------------------------------------

I have a Win32 C application that loads up the .NET CLR via
CorBindToRuntimeEx(). I creates an instance of a C# class that uses
DllImport statements to link back into a Win32 C DLL that has several
helper functions.

The only time that this error comes up is when I run in debug mode AND when
I have VS2005 startup the Win32 appplication. If I have VS2005 startup the
C# DLL and tell it to launch (ie. Start External Program) the Win32
application it works fine. It only seems to show up when I have a helper
(Win32 C DLL) function that returns a char*. If they return int, float,
etc. I do not get this error.

Is there something special with char*'s being returned from C code when
called via C# and DllImport?

Sorry for the lack of info - it is one of those hard to describe setups!

Here is what it looks like from a flow standpoint:

(Win32 C console app)
-> (loads up .NET CLR)
-> (creates instance of class within C# DLL)
-> (C# class makes calls to Win32 C DLL)

Here is a sample function I am using that just returns a hard coded string:

Win32 C DLL function def (cfile.dll):
extern "C" __declspec(dllexport) char* __stdcall TEST( )
{
return "hello world from TEST() function";
}

C# DllImport:
[DllImport("cfile.dll")]
public static extern String TEST();

Not sure what else to say... cannot really post sample projects so
hopefully someone can help without 'em!

Re: Memory error with funcs that return char* Chuck
10/30/2006 7:20:02 PM
Mattias,

Thanks for the response. I am not at work right now so I am guessing at the
code examples below.

Something like this:
[DllImport("cfile.dll")]
public static extern IntPtr TEST();

and call it in C# like this:

String tmp;
tmp = Marshal.PtrToStringAnsi(TEST());

If this is correct then I guess I would have to do it every time I called
the C DLL function from within C#? Anyway of getting around that? The
reason I ask is because my customers will be writing C# code that uses the
helper functions in the C DLL (think of C# as being like a scripting
language). I would like to make it easy as possible for them to use.

Also, any links to where this type of information is described at by
chance? I would like to read up on it more if you do. Maybe a best
practices or something similar?

Thanks,
Chuck


[quoted text, click to view]

Re: Memory error with funcs that return char* Mattias Sjögren
10/30/2006 11:49:53 PM
[quoted text, click to view]

When you declare the return type as string the CLR will try to free
the returned native string. To prevent that, declare it as IntPtr
instead and use Marshal.PtrToStringAnsi to get the characters instead.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Re: Memory error with funcs that return char* Mattias Sjögren
11/5/2006 3:53:25 PM
[quoted text, click to view]

That's find as long as the C code returns a static string that doesn't
have to be freed.


[quoted text, click to view]

I wouldn't recomment exposing DllImported functions directly anyway.
Wrap it up in a more .NET friendly interface that hides the
implementation details of calling the C API.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Re: Memory error with funcs that return char* Chuck C
11/7/2006 5:04:27 AM
Mattias,

Thanks for the input. What I ended up doing is what you suggested (what a
coinkydink!)

I have a base class that has DllImports marked as Private, and then wrapper
functions that are Public that do any extra conversion (such as the char *
return value). Worked out great!

Thanks for the help!

Mattias Sjögren <mattias.dont.want.spam@mvps.org> wrote in
news:Ov6zVoOAHHA.4844@TK2MSFTNGP02.phx.gbl:

[quoted text, click to view]
AddThis Social Bookmark Button