Reputation: 97
How can I use a Unicode PWideChar in Delphi to call a C++ function in a DLL? I want to send a string from Delphi to C++ and modify it.
function Test(a: PWideChar): Integer; cdecl; external 'c:\Win32Project1.dll' name 'Test';
extern "C" __declspec(dllexport) int __cdecl Test(char* a)
{
a = "汉语";
return 0;
}
Upvotes: 1
Views: 1691
Reputation: 613441
Typically the caller allocates a buffer which is passed to the callee, along with the buffer length. The callee then populates the buffer.
size_t Test(wchar_t* buff, const size_t len)
{
const std::wstring str = ...;
if (buff != nullptr)
wcsncpy(buff, str.c_str(), len);
return str.size()+1; // the length required to copy the string
}
On the Delphi side you would call it like this:
function Test(buff: PWideChar; len: size_t): size_t; cdecl; external "mydll.dll";
....
var
buff: array [0..255] of WideChar;
s: string;
....
Test(buff, Length(buff));
s := buff;
If you don't want to allocate a fixed length buffer, then you call the function to find out how large a buffer is needed:
var
s: string;
len: size_t;
....
len := Test(nil, 0);
SetLength(s, len-1);
Test(PWideChar(s), len);
If you wish to pass a value to the function, I suggest that you do that through a different parameter. That makes it more convenient to call, and does not force you to make sure that the input string has a buffer large enough to admit the output string. Maybe like this:
size_t Test(const wchar_t* input, wchar_t* output, const size_t outlen)
{
const std::wstring inputStr = input;
const std::wstring outputStr = foo(inputStr);
if (buff != nullptr)
wcsncpy(buff, outputStr.c_str(), len);
return outputStr.size()+1; // the length required to copy the string
}
On the other side it would be;
function Test(input, output: PWideChar; outlen: size_t): size_t; cdecl;
external "mydll.dll";
And the calling code should be obvious.
Upvotes: 4