我有一个用C ++编写的dll,我需要在我的C#代码中使用此dll。搜索之后,我发现使用P / Invoke可以访问所需的函数,但是这些函数是在类中定义的,并且使用非静态私有成员变量。因此,我需要能够创建此类的实例以正确使用这些功能。如何获得对此类的访问权限,以便可以创建实例?我一直无法找到一种方法来做到这一点。
我想我应该注意,C ++ dll不是我的代码。
Answers:
无法在C#代码中直接使用C ++类。您可以间接使用PInvoke来访问您的类型。
基本模式是为Foo类中的每个成员函数创建一个关联的非成员函数,以调用该成员函数。
class Foo {
public:
int Bar();
};
extern "C" Foo* Foo_Create() { return new Foo(); }
extern "C" int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); }
extern "C" void Foo_Delete(Foo* pFoo) { delete pFoo; }
现在只需将这些方法调用到您的C#代码中即可
[DllImport("Foo.dll")]
public static extern IntPtr Foo_Create();
[DllImport("Foo.dll")]
public static extern int Foo_Bar(IntPtr value);
[DllImport("Foo.dll")]
public static extern void Foo_Delete(IntPtr value);
缺点是您将要传递一个笨拙的IntPtr,但是围绕此指针创建C#包装器类以创建更可用的模型是一件简单的事情。
即使您不拥有此代码,也可以创建另一个DLL,该DLL包装原始DLL并提供一个小的PInvoke层。
extern "C" { .... }
吗?或者纯粹在C ++中做就可以了?
C ++代码,ClassName.h
class __declspec(dllexport) CClassName
{
public:
CClassName();
~CClassName();
void function();
};
C ++代码ClassName.cpp
CClassName::CClassName()
{
}
CClassName::~CClassName()
{
}
void CClassName::function()
{
std::cout << "Bla bla bla" << std::endl;
}
C ++代码,用于调用者函数的ClassNameCaller.h文件
#include "ClassName.h"
#ifdef __cplusplus
extern "C" {
#endif
extern __declspec(dllexport) CClassName* CreateClassName();
extern __declspec(dllexport) void DisposeClassName(CClassName* a_pObject);
extern __declspec(dllexport) void function(CClassName* a_pObject);
#ifdef __cplusplus
}
#endif
C ++代码,用于调用者函数的ClassNameCaller.cpp文件
#include "ClassNameCaller.h"
CClassName* CreateClassName()
{
return new CClassName();
}
void DisposeClassName(CClassName* a_pObject)
{
if(a_pObject!= NULL)
{
delete a_pObject;
a_pObject= NULL;
}
}
void function(CClassName* a_pObject)
{
if(a_pObject!= NULL)
{
a_pObject->function();
}
}
C#代码
[DllImport("ClassNameDll.dll")]
static public extern IntPtr CreateClassName();
[DllImport("ClassNameDll.dll")]
static public extern void DisposeClassName(IntPtr pClassNameObject);
[DllImport("ClassNameDll.dll")]
static public extern void CallFunction(IntPtr pClassNameObject);
//use the functions
IntPtr pClassName = CreateClassName();
CallFunction(pClassName);
DisposeClassName(pClassName);
pClassName = IntPtr.Zero;
这是如何从VB调用C ++类方法的示例-对于C#,您只需要在步骤4中重写示例程序即可。