Delphi10.3.X跨平台调用动态链接库

2019-05-20 跨平台调用动态库

Windows平台

Windwos平台使用 静态加载方式加载dll

  1. C++代码

我使用的我是使用vs2019

#include <iostream>
using namespace std;


extern "C" int __declspec(dllexport) __stdcall stdadd(int x, int y);

int stdadd(int x, int y)
{
	cout << "我是C++里面的输出语句" << endl;
	return x + y;
}
  1. Delphi代码
// 声明调用
function Tadd(a, b: Integer): Integer; stdcall; external 'Cpp_Windows_Dll_Demo' name 'stdadd';

Writeln(Tadd(10, 20));

  1. 结果
    在这里插入图片描述

网上有朋友说stdadd函数名称会变,但是我这里没有啊(可以使用Dll Export Viewer工具查看一下编译后的dll文件的函数名)
在这里插入图片描述

Linux

Linux平台目前测试只能使用动态加载方式来使用

  1. C++ 代码,文件后缀名为.cpp
#include <iostream>
using namespace std;


//extern "C" int __declspec(dllexport) __stdcall stdadd(int x, int y);

int stdadd(int x, int y)
{
        cout << "我是C++里面的输出语句" << endl;
        return x + y;
}

编译:

    g++ test_so.cpp -fPIC -shared -o libnum.so

查看so文件的函数

   # 下面命令任选一条
    nm -D libnum.so | grep stdadd
    objdump -tT libnum.so  | grep stdadd

函数名变了
在这里插入图片描述

如果是C语言的话就不会变

  • 把cpp文件改为c后缀名;
  • 执行:gcc test_so.cpp -fPIC -shared -o libnum.so 编译so文件
  • 查看函数,我这里把stdadd函数改为了add
    在这里插入图片描述
  1. Delphi代码
// 定义一个函数指针
var
  MyFun: function(a, b: Integer): Integer;

if not FileExists('/home/parallels/桌面/Tools/Test/so/libnum.so') then
    begin
      Writeln('libnum.so文件不存在');
    end
    else
    begin
      try
        Hand := LoadLibrary('/home/parallels/桌面/Tools/Test/so/libnum.so');
        if Hand <> 0 then
        begin
          Writeln('so文件加载成功');
          MyFun := GetProcAddress(Hand, '_Z6stdaddii');
          Writeln(MyFun(30, 10));
        end;

      finally
        FreeLibrary(Hand);
      end;

    end;

  1. 执行结果
    在这里插入图片描述

完整的Delphi跨平台代码

program Demo01_Call_CppDll;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

{$IFDEF LINUX}
var
  MyFun: function(a, b: Integer): Integer;
{$ELSE}

function Tadd(a, b: Integer): Integer; stdcall; external 'Cpp_Windows_Dll_Demo' name 'stdadd';
{$ENDIF}

var
  Hand: Cardinal;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    Writeln('Call so');
    {$IFDEF LINUX}
    if not FileExists('/home/parallels/桌面/Tools/Test/so/libnum.so') then
    begin
      Writeln('libnum.so文件不存在');
    end
    else
    begin
      try
        Hand := LoadLibrary('/home/parallels/桌面/Tools/Test/so/libnum.so');
        if Hand <> 0 then
        begin
          Writeln('so文件加载成功');
          MyFun := GetProcAddress(Hand, '_Z6stdaddii');
          Writeln(MyFun(30, 10));
        end;

      finally
        FreeLibrary(Hand);
      end;

    end;
    {$ELSE}
    Writeln(Tadd(10, 20));
    {$ENDIF}
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值