Функция DLL, которая экспортирует указатель в программу Delphi - PullRequest
0 голосов
/ 20 января 2019

У меня есть простая программа, которая экспортирует 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 голосов
/ 21 января 2019

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;

Для целей взаимодействия между языками / компиляторами, единственный переносимый вызовусловные обозначения cdecl и stdcall.Если в коде не указано соглашение о вызовах, по умолчанию, используемое большинством компиляторов C и C ++, является __cdecl (но обычно его можно указать в настройках компилятора), в то время как Delphi по умолчанию использует register (__fastcall в C++ Builder).

Когда параметры или возвращаемое значение не используются, как в DisplayHelloFromDLL(), объявление неправильного соглашения о вызовах на самом деле не имеет значения.Но когда используются параметры и / или возвращаемое значение, как в FuncInit2(), объявление правильного соглашения о вызовах имеет значение.См. Подводные камни преобразования для получения дополнительной информации.

Итак, две рассматриваемые функции DLL, вероятно, должны быть объявлены в Delphi следующим образом:

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';

ЕслиDLL использует файл .def для удаления искажения имени из экспортированных имен, вы можете опустить атрибут name:

type
  function_config = ...;
  pfunction_config = ^function_config;

procedure DisplayHelloFromDLL; cdecl; external 'SDK_DLL.dll';
function FuncInit2: pfunction_config; cdecl; external 'SDK_DLL.dll';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...