Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The generated .cs file doesn't work (Unhandled exception. System.EntryPointNotFoundException) #533

Open
Hancapo opened this issue Mar 7, 2024 · 5 comments

Comments

@Hancapo
Copy link

Hancapo commented Mar 7, 2024

I have the intention to generate bindings for a certain library, so in order to get used to it I did my own addition and subtraction C++ library.

Windows 11 23H2 (Build 22631.3235)
ClangSharpPInvokeGenerator 17.0.1
JetBrains Rider 2023.3.3

sumarrestar.h

#pragma once

#ifndef SUMARRESTAR_H
#define SUMARRESTAR_H

class SumarRestar
{
public:
    static int sumar(int a, int b);
    static int restar(int a, int b);
};
#endif

sumarrestar.cpp

#include "sumarrestar.h"

int SumarRestar::sumar(int a, int b)
{
    return a + b;
}

int SumarRestar::restar(int a, int b)
{
    return a - b;
}

I would ideally like to avoid any changes to the original C++ code or at least they should be as minimal as possible.

Compilation settings:

image

The command line I used to generate it:

ClangSharpPInvokeGenerator --file "C:\Users\myusername\RiderProjects\SumarRestar\SumarRestar\sumarrestar.h" --libraryPath SumarRestar.dll -n SumarRestarSharp -o "C:\testing\SumarRestarSharp.cs"

The generated .cs file:

using System.Runtime.InteropServices;

namespace SumarRestarSharp
{
    public partial struct SumarRestar
    {
        [DllImport("SumarRestar.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?sumar@SumarRestar@@SAHHH@Z", ExactSpelling = true)]
        public static extern int sumar(int a, int b);

        [DllImport("SumarRestar.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?restar@SumarRestar@@SAHHH@Z", ExactSpelling = true)]
        public static extern int restar(int a, int b);
    }
}

The error I'm getting from the IDE:

Unhandled exception. System.EntryPointNotFoundException: Unable to find an entry point named '?sumar@SumarRestar@@SAHHH@Z' in DLL 'SumarRestar.dll'.

@myd7349
Copy link
Contributor

myd7349 commented Jul 15, 2024

When using PInvoke to call a class implemented in C++, it's important to note that the same C++ class method may have different decorated names in x86 and x64 environments. This means you'll need two separate PInvoke declarations for the same method, each targeting x86 and x64 platforms respectively, and then you'll need to manually determine which version to call in your code.

https://github.com/myd7349/Ongoing-Study/tree/master/c%23/Console/PInvoke/MarshalCppClassV1

@myd7349
Copy link
Contributor

myd7349 commented Jul 15, 2024

ClangSharpPInvokeGenerator also provides the following options:

  • -m32
  • -m64

@Hancapo
Copy link
Author

Hancapo commented Jul 15, 2024

I just need x64 modules, nothing else, I tried using the -m64 flag and I still get the same error.

@myd7349
Copy link
Contributor

myd7349 commented Jul 15, 2024

You can use this tool to inspect the exposed functions/methods in the C++ DLL. Make sure to check the option to leave the decorations alone.

What is the target architecture of your C# project? Is it AnyCPU or x64?

@tannergooding
Copy link
Member

In general binding against C++ is error prone and undesirable due to having an unstable ABI and no standard for exports across platforms/architectures.

Its typically recommended to have a C wrapper over your C++ and then bind against the C wrapper instead.

ClangSharp does get the mangled name directly from Clang but what that name is depends on several factors such as the CPU architecture (x86, x64, Arm64, etc) and the OS (Windows, Linux, MacOS, etc). So you may need to specify -m64 to ensure you have the right bitness and -c unix-types or -c windows-types if you want to explicitly use Unix vs Windows mangling.

Clang however does not work "perfectly" for cross compilation and so simplify specifying -c unix-types on Windows or -c windows-types on Unix may still result in other quirks in the codegen. That is a limitation of Clang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants