Henry
Henry

Reputation: 777

Passing PChar from Delphi DLL to C

I am currently having trouble importing a Delphi DLL dynamically. The Delphi DLL function is declared as here :

function TEST() : PChar; cdecl;
begin
  Result := '321 Test 123';
end;

In C++ I am calling it this way:

typedef char *TestFunc(void);
TestFunc* Function;
HINSTANCE hInstLibrary = LoadLibrary("Test.dll");
if (hInstLibrary)
{
    Function = (TestFunc*)GetProcAddress(hInstLibrary, "TEST");
    if (Function)
    {
        printf("%s", Function());
    }
}

The problem is that I am only receiving the first letter of the string. How can I tell C++ that the string is not ending after the first char?

Thanks

Upvotes: 2

Views: 2333

Answers (1)

David Heffernan
David Heffernan

Reputation: 613481

You have two problems:

  1. The string that Delphi is sending to you is UTF-16 encoded. You'd need to encode as ANSI and return PAnsiChar, if you want to match up against char*.
  2. The memory that the returned pointer refers to is liable to be deallocated when the function returns. You get away with it in your function since you return a string literal which is held as a global constant that endures for the lifetime of the DLL. For a string variable, you will encounter runtime errors when your caller tries to read memory that has been deallocated. To confuse matters, those runtime errors will be intermittent. Your code may appear to work. Expect failures when you deploy to your most important customer!

Your options to solve item 2:

  1. Arrange that the caller allocates the buffer, which can then be populated by the callee.
  2. Allocate and deallocate the string on a shared heap. For example the COM heap with CoTaskMemAlloc and CoTaskMemFree. Using a shared heap allows you to allocate in one module, and deallocate in the other.

As a rule of thumb, always prefer option 1 if it can meet your needs.

Upvotes: 2

Related Questions