Delphi 如何调用 VC 的类的成员函数(二) --- 内存模式

5 篇文章 0 订阅

https://blog.csdn.net/dbyoung/article/details/94576926  这篇文章中,
调用 VC 的 C++ Class 类导出的 DLL 函数时,需要在 VC 中,对对象进行实例化。
不在 VC 中实例化,在 Delphi 实例化可不可行?答案是肯定的。

譬如 C++ Class Dll:

// 这是已导出类的构造函数。
CppDll::CppDll()
{
    return;
}

int CppDll::MyAdd(int a, int b)
{
    return a + b;
}

void CppDll::ShowMSG()
{
    ::MessageBoxA(0, (LPCSTR)"Delphi 调用 VC 类的成员函数", (LPCSTR)"系统提示:", MB_OK);
}

用  depends 查看导出函数
x86:

public: __thiscall CppDll::CppDll(void)
public: class CppDll & __thiscall CppDll::operator=(class CppDll &&)
public: class CppDll & __thiscall CppDll::operator=(class CppDll const &)
public: int __thiscall CppDll::MyAdd(int,int)
public: void __thiscall CppDll::ShowMSG(void)

x64:

public: __cdecl CppDll::CppDll(void) __ptr64
public: class CppDll & __ptr64 __cdecl CppDll::operator=(class CppDll && __ptr64) __ptr64
public: class CppDll & __ptr64 __cdecl CppDll::operator=(class CppDll const & __ptr64) __ptr64
public: int __cdecl CppDll::MyAdd(int,int) __ptr64
public: void __cdecl CppDll::ShowMSG(void) __ptr64

第一个为类的构造函数(thiscall,cdecl,是 VC 默认的调用约定,当然可以自行修改)。
最后两个是 C++ Class 类导出的函数,我们希望在 Delphi 中调用的(x86 与 x64 的函数导出是有细微差别的)。
Delphi 中,先对函数进行申明:

{$IFDEF WIN32}
function CreateCppClass: Pointer; stdcall; external 'vcd.dll' name '??0CppDll@@QAE@XZ';                      // 创建 C++ 类
function CppClass_MyAdd(a, b: Integer): Integer; stdcall; external 'vcd.dll' name '?MyAdd@CppDll@@QAEHHH@Z'; // C++ 类的导出函数 MyAdd
procedure CppClass_ShowMSG; stdcall; external 'vcd.dll' name '?ShowMSG@CppDll@@QAEXXZ';                      // C++ 类的导出函数 ShowMSG
{$ELSE}
function CreateCppClass: Pointer; cdecl; external 'vcd.dll' name '??0CppDll@@QEAA@XZ';                      // 创建 C++ 类
function CppClass_MyAdd(a, b: Integer): Integer; cdecl; external 'vcd.dll' name '?MyAdd@CppDll@@QEAAHHH@Z'; // C++ 类的导出函数 MyAdd
procedure CppClass_ShowMSG; cdecl; external 'vcd.dll' name '?ShowMSG@CppDll@@QEAAXXZ';                      // C++ 类的导出函数 ShowMSG
{$ENDIF}

先实例化类(先定义一个成员变量:FCppClassObj: Pointer):

  GetMem(FCppClassObj, 8);
  FCppClassObj := CreateCppClass;

封装一下调用:

function TForm1.MyAdd({$IFDEF WIN32}a, b: Integer; pObj: Pointer{$ELSE}pObj: Pointer; a, b: Integer {$ENDIF}): Integer;
begin
  Result := CppClass_MyAdd(a, b);
end;

procedure TForm1.ShowMSG({$IFDEF WIN32}R1, R2: Integer; {$ENDIF} pObj: Pointer);
begin
  CppClass_ShowMSG;
end;

这样类就实例化完成了。下面我们就可以调用类的导出函数了:

{$IFDEF WIN32}
  Caption := IntToStr(MyAdd(4, 6, FCppClassObj));
  ShowMSG(0, 0, FCppClassObj);
{$ELSE}
  Caption := IntToStr(MyAdd(FCppClassObj, 4, 6));
  ShowMSG(FCppClassObj);
{$ENDIF}

OK,成功!
因为使用了内存的方式,在 Delphi 中进行了 C++ Class 的实例化。所以我称之为内存模式。
测试源码:https://github.com/dbyoung720/DCallCppClassDll.git
测试环境: WIN10X64+Delphi10.3+VS2019

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值