4

I am coding a sample to use c# code to call some function in c++ shared library. The environment is Ubuntu 16.04 and .NET Core 2.0.

       class Program
       {
           [DllImport("libc.so.6")]
            private static extern int getpid();           
           [DllImport("/home/xxx/invoke/hi.so")]
            private static extern int Sayhi();

           static void Main(string[] args)
           {
            int pid= getpid();
            Console.WriteLine(pid);
            Console.WriteLine("Hello World!");
            int status= Sayhi();
            Console.WriteLine(status);

            }
        }

the cpp:

#include <iostream>
using namespace std;
int Sayhi(){
cout<<"hello world from cpp!"<<endl;
return 1;
}

If I run the c# code, I get the error message:

Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry point named 'Sayhi' in DLL '/home/xxx/invoke/hi.so'.
   at invoke.Program.Sayhi()
   at invoke.Program.Main(String[] args) in /home/xxx/invoke/Program.cs:line 17

I think the compiler may change the name of the function so it can't be found. How to fix it?

Heartlocker
  • 43
  • 1
  • 4
  • Looks like [name mangling](https://en.wikipedia.org/wiki/Name_mangling#C.2B.2B) in action. Check [this](https://stackoverflow.com/questions/2804893/c-dll-export-decorated-mangled-names) – vasek Aug 09 '17 at 08:24

1 Answers1

5

You need to mark your C++ function as extern "C" so that the .NET Core runtime can find the function name.

Martin Ullrich
  • 78,211
  • 20
  • 211
  • 189
  • If this answer solves your problem, consider [accepting the answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). – Martin Ullrich Aug 09 '17 at 08:42
  • @ Martin Ullrich if I don't have the source code. Is there any way to force the compiler not to mangle the name. I know how to do it in windows but no idea about linux – Heartlocker Aug 09 '17 at 08:46
  • The name is read from the symbol table using C naming conventions. But you can also specify the fully mangled names in [`DllImport`'s `EntryPoint` property](https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.entrypoint(v=vs.110).aspx) – Martin Ullrich Aug 09 '17 at 08:50
  • If you don't have the source code, how are you going to compile the library with different options? – Eric Mellino Aug 09 '17 at 18:41
  • I saw that most of the C++ class library now use only extern for class library functions. So If we can't call only extern method from .Net Core then that is a problem for existing dll without source code modification. Also, there have another problem all of the C++ standard libraries do not support extern "C". If is there have any solution for calling extern functions from.Net core please mention here. – Md. Rashidul Hasan May 15 '18 at 05:26