导出指针的DLL函数执行Delphi程序

时间:2019-01-20 20:39:58

标签: c++ delphi

我有一个导出DLL的简单程序,该DLL从另一个DLL导出功能:

// SDK_DLL.cpp : 

#include "functions.h"
#include "functions_advanced.h" 
#include "stdafx.h"
#include <stdio.h>
using namespace std;

extern "C"
{
    __declspec(dllexport) void DisplayHelloFromDLL()
    {
        printf("Hello from DLL...");
    }

    __declspec(dllexport) function_config FuncInit = appd_config_init();

    __declspec(dllexport) function_config * FuncInit2()
    {
        function_config* cfg = function_config_init();
        return cfg;
    }
}

function_config_init()返回一个指针,我似乎找不到找到适当的导出声明的方法。

我正在以这种方式向Delphi加载一个简单的函数:

procedure DisplayHelloFromDLL; external 'C:\Users\Administrator\Documents\Visual Studio 2017\Projects\SDK_DLL\Debug\SDK_DLL.dll';

我是否需要更改加载此指针返回函数的方式?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

FuncInit是导出的变量。 Delphi不支持通过external导入变量,仅支持函数。如果您需要导入FuncInit,则必须直接使用GetProcAddress()在运行时获取指向变量的指针:

type
  // you did not show the C/C++ declaration
  // of function_config, so I can't provide
  // a translation here, but it is likely to
  // be a struct, which is a record in Delphi ...
  function_config = ...;
  pfunction_config = ^function_config;

function GetFuncInit: pfunction_config;
begin
  Result := pfunction_config(GetProcAddress(GetModuleHandle('SDK_DLL.dll'), 'FuncInit'));
end;

var
  FuncInit: pfunction_config;

FuncInit := GetFuncInit;

出于跨语言/编译器互操作的目的,唯一的可移植调用约定为cdeclstdcall。当代码中未指定调用约定时,大多数C和C ++编译器使用的默认设置为__cdecl(但通常可以在编译器设置中指定),而Delphi使用的默认设置为register({{ C ++ Builder中的{1}}。

__fastcall中未使用任何参数或返回值时,则声明错误的调用约定并不重要。但是,当使用参数和/或返回值时(例如在DisplayHelloFromDLL()中),则声明正确的调用约定很重要。有关更多详细信息,请参见Pitfalls of converting

因此,可能需要像在Delphi中那样声明两个有问题的DLL函数:

FuncInit2()

如果DLL使用type function_config = ...; pfunction_config = ^function_config; procedure DisplayHelloFromDLL; cdecl; external 'SDK_DLL.dll' name '_DisplayHelloFromDLL'; function FuncInit2: pfunction_config; cdecl; external 'SDK_DLL.dll' name '_FuncInit2'; 文件从导出的名称中删除名称修饰,则可以省略.def属性:

name