Вы пытаетесь сначала вызвать функцию DLL, а затем привести ее возвращаемое значение к указателю на функцию. Вы не можете назначить указатель функции на указатель BSTR
, на что жалуется компилятор.
Вам нужно привести указатель функции к типу, прежде чем вы сможете правильно вызвать функцию. Вы пытаетесь сделать это при вызове функции, но чтобы сделать это правильно, вам нужно сделать это следующим образом:
BSTR bstr = ((GetLastErrText_funtype)GetLastErrText)(); // <-- note the extra parenthesis around the cast!
В противном случае было бы лучше привести указатель функции при первом получении, а затем при необходимости вызвать его как обычную функцию:
typedef BSTR (__stdcall* GetLastErrText_funtype)();
GetLastErrText_funtype GetLastErrText = (GetLastErrText_funtype) GetProcAddress(dll_module, "GetLastErrText");
...
BSTR bstr = GetLastErrText();
Не забудьте освободить BSTR
, когда вы закончите использовать его (при условии, что DLL правильно распределяет его с помощью одной из SysAllocString...()
функций):
BSTR bstr = GetLastErrText();
std::cout << "\nstr = "; // <-- std::cout does not support wchar_t data!
std::wcout << bstr; // <-- use std::wcout instead...
SysFreeString(bstr); // <-- free it!
ОБНОВЛЕНИЕ : код Delphi вашей DLL фактически не возвращает необработанный указатель BSTR
, как ожидает ваш код C ++. Фактически он возвращает WideString
, который является управляемым типом в Delphi, и всегда возвращается из функции через скрытый выходной параметр, который ваш код C ++ не заполняет. Вот почему ваш код C ++ терпит неудачу. См. Почему WideString не может использоваться как возвращаемое функцией значение для взаимодействия? . Правильная сигнатура функции на стороне C ++ должна выглядеть примерно так:
typedef void (__stdcall* GetLastErrText_funtype)(WideString&);
Однако WideString
- это обертка для BSTR
, сама она не является фактическим BSTR. Вы не можете использовать WideString
как есть вне компиляторов Delphi и C ++ Builder.
Вам нужно переписать функцию DLL, чтобы сделать ее более совместимой с компиляторами не-C ++ Builder. Например:
function GetLastErrText: PWideChar; stdcall;
var
RealResult: WideString absolute Result;
begin
try
Initialize(RealResult);
RealResult := 'This is the result of GetLastErrText';
except
on E: Exception do
ShowMessage('Delphi exception::GetLastErrText : ' + E.Message);
end;
end;
В качестве альтернативы:
function GetLastErrText: PWideChar; stdcall;
begin
try
Result := nil;
WideString(Result) := 'This is the result of GetLastErrText';
except
on E: Exception do
ShowMessage('Delphi exception::GetLastErrText : ' + E.Message);
end;
end;