У меня есть простая программа, которая экспортирует 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';
Нужно ли мне изменить способ загрузки этой функции возврата указателя?
Спасибо большое за вашу помощь.





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';
Процедура неверна, потому что она неправильно понимает соглашение о вызовах. Трудно понять, что вы имеете в виду. Вы хотите знать синтаксис Delphi для функции. Наверняка вы найдете это в документации. Вы не можете выучить такой язык, задавая эти вопросы на SO. Вы также не можете надеяться учиться на проекте взаимодействия.