С++ использует Delphi DLL

Я не могу использовать функцию dll, разработанную в Delphi. У меня возникли некоторые трудности с преобразованием типов.

Это функция, которую я хочу вызвать в DLL:

function rData(ID: Cardinal; queue: WideString): WideString; stdcall;

Мой код на С++ был таким:

typedef string (*ReturnDataSPL)(DWORD, string);

string result;
HMODULE hLib;
hLib = LoadLibrary("delphi.dll");
pReturnDataSPL = (ReturnDataSPL)GetProcAddress(hLib,"rData");
if (NULL != pReturnDataSPL)
   result = pReturnDataSPL(JobID,printerName);

Проблема в том, что я не могу заставить его работать. Я не знаю, какой тип совместим с Delphi WideString и Cardinal.

Кто-нибудь Помогите мне

ИЗМЕНИТЬ:

Это функция, которую я хочу вызвать в DLL:

procedure rData(ID: Cardinal; queue: WideString; var Result: WideString); stdcall;

После изменения код выглядел так:

typedef void (__stdcall *ReturnDataSPL)(DWORD, BSTR, BSTR&);

HMODULE hLib;
BSTR result = NULL;
hLib = LoadLibrary("delphi.dll");

pReturnDataSPL = (ReturnDataSPL)GetProcAddress(hLib,"rData");
if (NULL != pReturnDataSPL)
{
   pReturnDataSPL(JobID,(BSTR)"Lexmark X656de (MS) (Copiar 2)",result);
}

person msantiago    schedule 02.04.2013    source источник


Ответы (1)


У вас очень мало шансов вызвать эту функцию.

Для начала ваш текущий код не может надеяться на успех, так как я предполагаю, что string равно std::string. Это тип данных C++, который код Delphi не может ни предоставить, ни использовать. Чтобы сопоставиться с Delphi WideString, вам нужно использовать тип данных COM BSTR.

Другая проблема с вашим кодом в его нынешнем виде заключается в том, что он использует cdecl на стороне C++ и stdcall на стороне Delphi. Вам нужно согласовать соглашения о вызовах.

Однако это также не удастся из-за разницы между ABI Delphi для возвращаемых значений и стандартом платформы. Эта тема была подробно рассмотрена здесь: -interop">Почему WideString нельзя использовать в качестве возвращаемого значения функции для взаимодействия?

Лучше всего прекратить использовать WideString в качестве возвращаемого значения и преобразовать его в ссылочный параметр C++. Вы захотите преобразовать Delphi в соответствие.

Вы смотрите на что-то вроде этого:

Дельфи

procedure rData(ID: Cardinal; queue: WideString; var Result: WideString); stdcall;

С++

typedef void (__stdcall *ReturnDataSPL)(DWORD, BSTR, BSTR&);
person David Heffernan    schedule 02.04.2013
comment
Я изменил код, как указано выше: Но когда функция выполняется, я получаю исключение: «Необработанное исключение по адресу 0x772b15ee в CallbackSample.exe: 0xC0000005: местоположение чтения нарушения доступа 0x00000000». что это может быть? Спасибо - person msantiago; 02.04.2013
comment
Ваш код C++ не совпадает с моим. Третий параметр должен передаваться по ссылке. Сравните разницу между вашим кодом и моим. Кроме того, вы не можете просто создать BSTR. Вы должны сделать настоящий BSTR! - person David Heffernan; 02.04.2013
comment
SysAllocString для создания BSTR. Или используйте одну из удобных оберток BSTR. - person David Heffernan; 02.04.2013
comment
Хороший. Не забудьте освободить свои BSTR. - person David Heffernan; 02.04.2013
comment
Я бы использовал класс WideString в коде C++ для управления памятью BSTR. Для второго параметра вы можете использовать WideString::c_bstr(), чтобы передать значение BSTR в функцию. Для третьего параметра я бы изменил его объявление на BSTR*, а затем использовал переопределенный оператор & WideString, чтобы передать BSTR* функции, например: typedef void (__stdcall *ReturnDataSPL)(DWORD, BSTR, BSTR*); WideString result; pReturnDataSPL(JobID, WideString("Lexmark X656de (MS) (Copiar 2)").c_bstr(), &result); - person Remy Lebeau; 03.04.2013
comment
@Remy WideString недоступен в большинстве компиляторов C++. Только в очень редко встречающемся компиляторе Embarcadero. Пока не указано иное, я предполагаю использование обычных компиляторов, MSVC или GNU. - person David Heffernan; 03.04.2013
comment
@DavidHeffernan: в других компиляторах доступны аналогичные классы, например _bstr_t или CComBSTR. - person Remy Lebeau; 03.04.2013
comment
@remy да, это то, что я имел в виду в предыдущем комментарии - person David Heffernan; 03.04.2013