我不能很好地使用C ++,但现在我需要构建一个调用Delphi DLL并将字符串传递给DLL并返回新字符串的函数。
这是我的Delphi DLL代码:
library testdll;
uses
System.Classes,Winapi.Windows,System.SysUtils;
{$R *.res}
function hello(name : PWideChar):PWideChar;
var
rs:PWideChar;
begin
rs:=PWideChar('Hello '+rs);
Result:=rs;
end;
exports
hello;
begin
end.
任何人都可以帮我在C ++中创建简单的代码来调用和获取结果形式的hello函数,谢谢你的帮助。
答案 0 :(得分:5)
您正在尝试将PWideChar连接到String文字并将其作为另一个PWideChar返回。这不会按原样运作。无论如何你不应该返回PWideChar。这导致了内存管理的噩梦。更好的设计是让调用者将缓冲区传递到DLL中以填充,例如:
library testdll;
uses
System.Classes,
Winapi.Windows,
System.SysUtils;
{$R *.res}
function hello(name, buffer : PWideChar; buflen: Integer): Integer; stdcall;
var
rs: UnicodeString;
begin
rs := 'Hello '+UnicodeString(name);
if buffer = nil then
begin
Result := Length(rs) + 1;
end else
begin
Result := Min(buflen, Length(rs));
Move(rs[1], buffer^, Result * SizeOf(WideChar));
end;
end;
exports
hello;
begin
end.
然后,给出这个C ++声明::
int __stdcall hello(wchar_t* name, wchar_t* buffer, int buflen);
根据您的需要,您可以通过各种不同的方式调用它:
wchar_t str[256];
int len = hello(L"joe", str, 255);
str[len] = 0;
...
int len = hello(L"joe", NULL, 0);
wchar_t *str = new wchar_t[len];
len = hello(L"joe", str, len);
str[len] = 0;
...
delete[] str;
int len = hello(L"joe", NULL, 0);
std::wstring str(len-1);
str.resize(hello(L"joe", &str[0], len));
...
int len = hello(L"joe", NULL, 0);
UnicodeString str;
str.SetLength(len-1);
str.SetLength(hello(L"joe", str.c_str(), len));
...
如果您需要在Delphi中使用相同的DLL,可以很容易地将相同类型的代码转换为Pascal:
function hello(name, buffer: PWideChar, buflen: Integer): Integer; stdcall; extern 'testdll.dll';
var
str: array[0..255] of WideChar;
len: Integer;
begin
len := hello('joe', str, 255);
str[len] := #0;
...
end;
var
str; PWideChar
len; Integer;
begin
len := hello('joe', nil, 0);
GetMem(str, len];
len := hello('joe', str, len);
str[len] := #0;
...
FreeMem(str);
end;
var
str; UnicodeString;
len; Integer;
begin
len := hello('joe', nil, 0);
SetLength(str, len-1);
SetLength(str, hello('joe', PWideChar(str), len));
...
end;
答案 1 :(得分:3)
更新事实证明,Delphi对WideString
返回值使用非标准调用约定。所以下面的代码不起作用。基本概念是合理的,但您需要返回BSTR
或使用类型为out
的{{1}}参数。更多详情:Why can a WideString not be used as a function return value for interop?
WideString
当然使用它。在Delphi中,BSTR
映射到WideString,它为我们提供了以下方法。
<强>的Delphi 强>
BSTR
<强> C ++ 强>
function concat(s1, s2: PWideChar): WideString; stdcall;
begin
Result := s1 + s2;
end;
显然在这个简单的例子中,连接字符串所需的缓冲区大小很容易计算。但是如果DLL中的实际功能更复杂,那么这种方法将变得更加明显有利。