mono / CppSharp

Tools and libraries to glue C/C++ APIs to high-level languages
MIT License
3.14k stars 518 forks source link

EntryPointNotFoundException with a simple example #161

Closed gpetrou closed 10 years ago

gpetrou commented 10 years ago

I am testing the usage of the library (CppSharp_VS2012_423_artifacts.zip) with a simple project in VS2012. I have the following three projects based on some test projects you have in the repository: Native.vcxproj with Native.h

#if defined(_MSC_VER)
#define DLL_API __declspec(dllexport)
#else
#define DLL_API
#endif

class DLL_API Foo
{
public:
     Foo();
     int A;
     float B;
const char* GetANSI();
};

and Native.cpp

#include "Native.h"  

const char* Foo::GetANSI()
{
 return "ANSI";
}

WrapperGenerator with Program.cs

using System;
using CppSharp;
using CppSharp.AST;
using CppSharp.Generators;

namespace WrapperGenerator
{
       class Program : ILibrary
      {
           static void Main(string[] args)
           {
                 ConsoleDriver.Run(new Program());
                 Console.ReadLine();
            }

           public void Setup(Driver driver)
           {            
        var options = driver.Options;
        options.Verbose = true;
        options.GeneratorKind = GeneratorKind.CSharp;          
        options.LibraryName = "Native";           
        options.Headers.Add(@"F:\Repositories\TestCppSharp\Source\Native\Native.h");
        options.OutputDir = @"F:\Repositories\TestCppSharp\Source\TestCppSharp\";            
        //options.TargetTriple = "i686-pc-win32";          
    }

    public void SetupPasses(Driver driver) { }
    public void Preprocess(Driver driver, ASTContext ctx)  { }
    public void Postprocess(Driver driver, ASTContext ctx) { }
   }

}

The Native.cs file is generated successfully and I have the following simple program in another project TestCppSharp

using System;
using Native;

 namespace TestCppSharp
 {
      class Program
     {
           static void Main(string[] args)
           {
                   Native.Foo d = new Foo();
                   Console.WriteLine(d.GetANSI());
           }
     }
  }

When I run this I get EntryPointNotFoundException inside Native.cs in

    public Foo()
    {
        __Instance = Marshal.AllocHGlobal(8);
        Internal.ctor_0(__Instance);
    }

Any ideas what might be wrong? Also, is the current Getting-Started documentation up-do-date? I could help with that if you want. In that guide the generated code does not include CppSharp.Runtime.ICppMarshal interface. Is it possible to do that in my example?

tritao commented 10 years ago

Are you compiling the native code to a DLL with VS?

EntryPointNotFoundException is thrown by the runtime when the native symbol in the P/Invoke is not found.

You can use the DLL Export Viewer to debug such problems, the DLL should be exporting the symbols the generated code references.

http://www.nirsoft.net/utils/dll_export_viewer.html

If they mismatch, you either are using the wrong ABI or target triplet.

gpetrou commented 10 years ago

Yes, I am compiling the native code to DLL. Shouldn't I? I noticed that when I build the Native.vcxproj the Native.dll has 29 KB size. I can see two items in the list when opened with DLL Export Viewer When I run the WrapperGenerator however the size is reduced to 6 KB and the DLL Export Viewer does not show any items in the list. I tried to use options.TargetTriple = "i686-pc-win32" or "x86_64-pc-win64" but it does not seem to make any difference. I guess the ABI should be the default one (Microsoft)? Do I need anything else besides the prebuild binaries in CppSharp_VS2012_423_artifacts.zip to run this?

tritao commented 10 years ago

Yes you should be compiling to DLL. Why is the size changing when you run the wrapper? That probably means that the output name in the options is set the same as the native library, which CppSharp then overwrites when it compiles the generated C# code. Can you try changing the output name in the options?

I don't think this is a bug in CppSharp, the same examples work in the testsuite.

gpetrou commented 10 years ago

Ooops, you are right, I thought I had different names but I apparently I was not. Regarding CppSharp.Runtime.ICppMarshal interface is that needed or I could set an option to remove it? It does not show up in the Getting-Started guide.

tritao commented 10 years ago

ICppMarshal interface is not really needed anymore, it's only used if you try to use the std::vector C# typemaps. I will add an option for it and disable by default so it's not as confusing and does not force every client to have a reference to CppSharp.Runtime.

gpetrou commented 10 years ago

That would be great! Thanks.