Добрый день. Подскажите как правильно:
1) Передать из приложения написанного на Delphi указатель на функцию в DLL написанного на C++ ?
2) Вызывать функцию из DLL с передачей параметров и вернуть результат?
Ну собственно как я решал этот вопрос.
1. Описал типы функций.
TSendPacketStr = procedure (pck: string; const tid: integer; const ToServer: Boolean);stdcall;
TGetConnectionName = function(id : integer):string;stdcall;
TGetConnectioIdByName = function(name : string):integer;stdcall;
PSendPacketStr = ^TSendPacketStr;
PGetConnectionName = ^TGetConnectionName;
PGetConnectioIdByName = ^TGetConnectioIdByName;
TCFunctionStruct = record
pSendPacketStr: PSendPacketStr;
pGetConnectionName: PGetConnectionName;
pGetConnectioIdByName: PGetConnectioIdByName;
end;
PCFunctionStruct = ^TCFunctionStruct;
2. Описал структуру функцию в которой буду передавать указатель в Delphi.
TSetCFStruct = function(const struct: PCFunctionStruct): Boolean; stdcall;
3. Создал переменную в которой буду хранить адрес функции.
SetCFStruct: TSetCFStruct;
4. Загружаю DLL. Нахожу адрес и записываю в переменную. А также передаю указатель на функцию.
@SetCFStruct:=GetProcAddress(hLib, 'SetFunctionStruct');
if(Assigned(SetCFStruct)) then
begin
ScriptStruct.pSendPacketStr:=@TPluginStructClass.SendPacketStr;
ScriptStruct.pGetConnectionName:=@TPluginStructClass.getConnectionName;
ScriptStruct.pGetConnectioIdByName:=@TPluginStructClass.getConnectioidByName;
SetCFStruct(@ScriptStruct);
end;
5. Описываю структуру функций и функцию которые я буду принимать в DLL написанную на C++.
// Структура скриптов
struct ScriptStruct
{
void(*sendPacketStr)(unsigned char* pck, const int tid, bool toServer);
char*(*getConnectionName)(int);
int(*getConnectioIdByName)(char* name);
};
/// Функция передачи указателя на ScriptStruct
DLL_API bool SetFunctionStruct(ScriptStruct * scriptStruct);
6. Далее в сpp пишу описание функци.
// Вызывается при включении плагина
DLL_API bool SetFunctionStruct(ScriptStruct * scriptStruct)
{
OutputDebugStringA("SetFunctionStruct\n");
_scriptStruct->getConnectionName(123); // <- Здесь я пытаюсь вызвать функцию из Delphi
return true;
}
7. Запускаю проект через дебагер, подключаю DLL.
Мы приходим в точку останова функции
function TPluginStructClass.getConnectionName(id: integer): string; stdcall;
begin
result := dmData.ConnectNameById(id); /// <- вызывается
end;
После чего возникает креш.