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


_______________________________________________
Mono-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to