Check if P/Invoke was successful

523 Views Asked by At

I am trying to use a P/Invoke method on Mono using Ubuntu 14.04:

C++ part:

#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)

EXTERN_DLL_EXPORT int SomeMethod(int num);

// and .cpp file with the actual implementation

C# part:

[DllImport(@"TestProj")]
extern static int SomeMethod(int n);

Console.WriteLine(SomeMethod(2));

However if I try to invoke the method, I always get NullReferenceException, I am wondering how can I find out if the exception was raised because P/Invoke failed, maybe because it wasn't able to properly load the method, or the null reference actually occurred inside the SomeMethod.

Thanks

1

There are 1 best solutions below

0
On BEST ANSWER

If the shared (native) library is not found, you receive:

XXXXX failed to initialize, the exception is: System.DllNotFoundException

If you have a entry point mismatch you would receive a:

XXXXX failed to initialize, the exception is: System.EntryPointNotFoundException

If the shared library was crashing you would never get the framework null ref.

So, the .so is being loaded and the 'c' function is being called, but something in the mono framework is throwing a fit. Marshaling interop is the first place I'd look. There is some mismatch between what you are passing from C# to Cpp or back... If the sample you give is true, just 'int', not pointers/structs/etc.. then it should just work.

The simplest Interop case HelloWorld I can create, give it a true and see what happens:

cat countbyone.cpp

extern "C" int SomeMethod(int num) {
  return num++;
}
  • gcc -g -shared -fPIC countbyone.cpp -o libcountbyone.so

  • or OS-X:
  • clang -dynamiclib countbyone.cpp -o libcoutbyone.dylib

cat interop.cs

using System;
using System.Runtime.InteropServices;
namespace InteropDemo
{
    class MainClass
    {
            [DllImport("countbyone")]
            private static extern int SomeMethod(int num);

        public static void Main (string[] args)
        {
            var x = SomeMethod(0);
            Console.WriteLine(x);
        }
    }
}

mcs interop.cs

mono interop.exe

Should should be 1 and no errors...