c# - 找不到入口点

标签 c# c++ pinvoke

我正在尝试使用 Platform Invoke 从 C# 执行 C++ DLL 中的一些函数。我收到一个 EntryPoint Not Found 错误,我无法找出原因。希望有人能帮助我。 :)

C++ 声明:

Declaration

C# PInvoke 代码:

PInvoke

转储和错误:

Dump enter image description here

编辑:使用 EntryPoint="?CreateClass@Drive@UnmanagedDLL@@QAEPAV12@XZ" 有效,但我不应该能够引用 CreateClass 吗?

最佳答案

此代码块:

extern "C" UNMANAGEDLL_API Drive* Drive::CreateClass()
{
    return new Drive();
}

您是否尝试使用 C 链接导出类方法?我想知道为什么它甚至可以编译。使用 C 链接导出的函数不应该是类方法:

Drive* Drive::CreateClass()
{
    return new Drive();
}

extern "C" UNMANAGEDLL_API Drive* CreateClass()
{
    return Drive::CreateClass();
}

这是因为 C 链接不能应用于类方法(它需要 thiscall 和名称修改)。你能DllImport类方法吗?首先忘记使用 C 链接,然后删除 extern "C"。现在您必须使用 EntryPoint 参数 DllImport raw 方法名称,但您还必须更改调用约定(因为默认为 StdCall 但是类使用 ThisCall),如果你忘记这个那么你就是在运行炸弹。一个示例(仅供引用,如果您可以访问类 API 并且可以添加 plain C 导出函数,我真的会避免这种情况):

[DllImport("SomeDll.dll",
    EntryPoint="?CreateClass@Drive@UnmanagedDLL@@QAEPAV12@XZ",
    CallingConvention = CallingConvention.ThisCall)]
public static extern IntPtr CreateClass(IntPtr thisPointer);

这样使用:

IntPtr drive = CreateClass(IntPtr.Zero);

现在您可以使用 drive 调用其他方法(您有权调用约定这样做,在 X86 上这是通过 ECX 传递的,而不是在堆栈中它会与 StdCall 一起使用,在 X64 上这是一个完全不同的故事,但使用属性它会在两者上工作)。

编辑

如何使用 C++/CLI 完成?它应该更容易且无痛(实现只是一个骨架)。

标题:

public ref class Drive sealed
{
public:
    ~Drive();

    // Assuming you want to keep a static factory method
    static Drive^ CreateClass();

    property bool State
    {
        bool get();
        void set(bool value);
    }

private:
    Drive();

    DriveNativeImpl* _drive;
};

实现:

Drive::Drive()
{
    _drive = new DriveNativeImpl();
}

Drive::~Drive()
{
    delete _drive;
}

Drive^ Drive::CreateClass()
{
    return gcnew Drive();
}

bool Drive::State::get()
{
    assert(_drive != null);

    return _drive->GetState();
}

void Drive::State::set(bool value)
{
    assert(_drive != null);

    _drive->SetState(value);
}

在 C# 中,您会看到一个普通托管类:

Drive drive = Drive.CreateClass();
drive.State = true;

关于c# - 找不到入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26524780/

相关文章:

c# - Lumenworks Csv 阅读器读取具有相同名称的列或避免使用 ` An item with the same key has already been added`

c++ - 在我的 Qt 应用程序中打开 Excel 并与之通信

c++ - 在 C++ 中调用辅助类的重写方法

c# - 在带参数的函数上使用 PInvoke 时出现 AccessViolationException

c# - 将 IWICStream/IStream 从非托管 C++ DLL 返回到托管 C# 并读取它

c# - 如何以另一个用户(la/netonly)身份启动 Internet Explorer 进程?

c# - +/- 登录 TimeSpan 的 ParseExact()?

c# - 为什么在动态创建事件处理程序时会出现参数异常?

c# - 行的最小高度 [Migradoc]

c++ - Chilliad 计算差异