我正在尝试使用Platform Invoke从C#执行C ++ DLL中的一些函数。我收到了一个未找到EntryPoint的错误,我无法弄清楚原因。希望有人可以帮助我。 :)
C ++声明:
C#PInvoke代码:
Dumpbin和错误:
编辑:使用EntryPoint="?CreateClass@Drive@UnmanagedDLL@@QAEPAV12@XZ"
有效,但我不应该引用CreateClass吗?
答案 0 :(得分:4)
此代码块:
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
并命名为mangling)。你可以DllImport
类方法吗?首先忘记使用C链接然后删除extern "C"
。现在,您必须使用DllImport
参数EntryPoint
原始方法名称,但您还必须更改调用约定(因为默认值为StdCall
,但类使用{{1} }}),如果你忘记,那么只需要你运行炸弹。一个例子(仅供参考,如果您可以访问类API并且可以添加 plain C导出函数,我会非常避免这种):
ThisCall
像这样使用:
[DllImport("SomeDll.dll",
EntryPoint="?CreateClass@Drive@UnmanagedDLL@@QAEPAV12@XZ",
CallingConvention = CallingConvention.ThisCall)]
public static extern IntPtr CreateClass(IntPtr thisPointer);
现在你可以使用IntPtr drive = CreateClass(IntPtr.Zero);
来调用其他方法(你有正确的调用约定,在X86上,这是通过drive
传递的,而不是像在{ECX
那样传递。 1}},在X64上,这是一个完全不同的故事,但使用属性,它将同时适用于两者。)
修改强>
如何使用C ++ / CLI完成?它应该更容易和无痛(实现只是一个骨架)。
部首:
StdCall
实现:
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;
};
在C#中,您会看到普通托管类:
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);
}