[Mono-list] Problems Using P/Invoke
Jonathan Pryor
jonpryor at vt.edu
Thu Nov 10 16:53:22 EST 2005
On Thu, 2005-11-10 at 23:51 +0800, Jeremy Tan wrote:
> I am trying to write some C# bindings for the C++ libdar library
> (http://dar.sourceforge.net)...
> The problem I am having now is that I can't seem to find a way
> to bind this library into C# APIs due to the way the functions are
> declared. I've tried searching the internet but I can't seem to find any
> information on this.
http://www.mono-project.com/dllimport
> I'm stuck at the first function that I'm trying to
> import and I can't go any further from this point as almost all the
> functions in the library are declared this way:
>
> extern void get_compile_time_features(bool & ea,
> bool & largefile,
> bool & nodump,
> bool & special_alloc,
> U_I & bits,
> bool & thread_safe,
> bool & libz,
> bool & libbz2,
> bool & libcrypto);
>
> The problem I have here is the way the parameters are defined. Note that
> the U_I type is just a typedef to unsigned int in libdar. In my source
> file, i declared it like this because I can't seem to find a way to
> specify "&" in the method signature:
`ref' is an appropriate mapping for `&'. You have several other
problems...
> [DllImport(library, CallingConvention = CallingConvention.Cdecl)]
> private unsafe extern static void get_compile_time_features(
> ref bool EAttributes,
> ref bool LFile,
> ref bool NDunp,
> ref bool SAllocation,
> ref uint bits,
> ref bool TSafe,
> ref bool LZ,
> ref bool LBZ2,
> ref bool LCrypto);
starting with this:
> Unhandled Exception: System.EntryPointNotFoundException:
> get_compile_time_features
> in (wrapper managed-to-native) LibDar.LibDar:get_compile_time_features
> (bool&,bool&,bool&,bool&,uint&,bool&,bool&,bool&,bool&)
> in <0x00054> LibDar.LibDar:GetCompileTimeFeatures ()
> in <0x00026> LibDar.Tester:Main (System.String[] args)
The problem is C++ name mangling. For "fun" run the nm(1) command on
your C++ library. The get_compile_time_features function is actually
the symbol _Z25get_compile_time_featuresRbS_S_S_RjS_S_S_S_ in your
library (or something similarly FUBAR). Mono/.NET do not understand C++
name mangling conventions (there'd be little point, since each C++
compiler has a different name mangling scheme).
The solution to this is ``extern "C"''. You'd have to either change the
get_compile_time_features declaration to this:
extern "C" void get_compile_time_features(bool & ea,
bool & largefile,
bool & nodump,
bool & special_alloc,
U_I & bits,
bool & thread_safe,
bool & libz,
bool & libbz2,
bool & libcrypto);
or you'd have to write a C wrapper for the C++ function.
The other problem you have is "bool". The size of "bool" varies between
compilers, and Mono marshals it as a short, which probably isn't what
the C++ compiler uses. Thus you have to determine what sizeof(bool) is
for your C++ compiler and use an appropriate type in your C#
declaration.
You may find SWIG to be useful: http://www.swig.org
- Jon
More information about the Mono-list
mailing list