[Mono-list] InteropServices: DllNotFoundException...?
Jonathan Pryor
jonpryor@vt.edu
Sun, 23 May 2004 16:39:32 -0400
On Sun, 2004-05-23 at 11:37, Simon Ask Ulsnes wrote:
> *sigh*
> Hooray for Managed Code! ;-)
>
> Could you please give a short example of a C++ library function that
> returns a string for use in a managed application? (with proper memory
> hygiene ;-)
Sure. I haven't tried to compile any of this, but it's the right
idea...
//
// Unmanaged C++ code
//
#include <string>
#include <stdlib.h>
/**
* To minimize library differences, this function should be used
* by "external" code (managed code, other 3rd party code) to
* free memory allocated within this library.
*
* This is particularly important on any platform that has
* multiple runtime libraries which each export "free" (say,
* Windows, with MSVCRT, GCC, Borland, and lots of other C
* runtime library implementations, all of which are
* mutually incompatible).
*/
extern "C" void
mylib_free (void* mem)
{
free (mem);
}
/**
* This is a function which returns a newly allocated string.
* Callers *must* use mylib_free() to free the returned memory.
*/
extern "C" char*
mylib_get_string ()
{
std::string s ("this is my string");
// manipulate `s' to fill its contents
// paranoia: check for integer overflow in buffer size
// calculation. Consider if s.size() is = 0xFFFFFFFF.
// 0xFFFFFFFF + 1 = 0, which is too small to hold the
// required string; any attempt to fill the buffer would
// result in memory corruption.
// Yes, this is likely absurd, as your app would likely
// have crashed by now if it had a string that big, but
// better safe than sorry.
// For more information, see:
// http://msdn.microsoft.com/security/securecode/columns/default.aspx?pull=/library/en-us/dncode/html/secure04102003.asp
std::string::size_type size = s.size();
if (size + 1 <= size) return NULL;
size += 1;
// return newly allocated string.
char *r = (char*) malloc (size);
if (!r) return NULL;
strcpy (r, s.c_str());
return r;
}
//
// Managed code
//
using System;
using System.Runtime.InteropServices;
class Mylib {
[DllImport ("mylib")]
private static extern void mylib_free (IntPtr r);
[DllImport ("mylib")]
private static extern IntPtr mylib_get_string ();
public static string GetString ()
{
IntPtr r = mylib_get_string ();
if (r == IntPtr.Zero) return null;
string s = null;
try {
s = Marshal.PtrToStringAnsi (r);
}
finally {
mylib_free (r);
}
return s;
}
}
- Jon