我正在尝试使用 Platform Invoke 从 C# 执行 C++ DLL 中的一些函数。我收到一个 EntryPoint Not Found 错误,我无法找出原因。希望有人能帮助我。 :)
C++ 声明:
C# PInvoke 代码:
转储和错误:
编辑:使用 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/