Einzelnen Beitrag anzeigen

mandoza

Registriert seit: 27. Apr 2018
16 Beiträge
 
#1

Delphi C++ Dll

  Alt 27. Jan 2019, 22:57
Delphi-Version: 10.2 Tokyo
Hello every one ; I've a C++ DLL that i want to consume from Delphi Project ; My C++ part is

Delphi-Quellcode:
//Header file UserIdentity.h
extern "C" {
#endif
struct UserIdentity
{
    const char* name;
    int id;
}
;
/**
 * Gets all of the UserIdentity objects currently available.
 * @param[out] pCount A pointer to storage for the number of UserIdentity objects available
 * @param[out] pUserIdentities A pointer to storage for a number of UserIdentity objects indicated by pCount
 * \n NOTE : Pass nullptr for pUserIdentities to get only the count value
 * @usage
 *
 * size_t userIdentitiesCount = 0;
 * UserIdentity* userIdentities = nullptr;
 * Ui_export(&userIdentitiesCount, nullptr);
 * if (userIdentitiesCount) {
*      userIdentities = new UserIdentity[userIdentitiesCount];
*      Ui_export(&userIdentitiesCount, userIdentities);
*      // Process userIdentities...
*      delete [] userIdentities;
*  }

 *
 */
EXAMPLE_LIBRARY_EXPORT void Ui_export(size_t* pCount, UserIdentity* pUserIdentities);
#ifdef __cplusplus
}
#endif
And here's my cpp fie " UserIdentity.cpp "

Delphi-Quellcode:
#include "UserIdentity.h"
#include <map>
static const std::map<std::string, int> gUserIdentites = {
    { "Bob", 100 }
,
    { "Jone", 101 },
    { "Alice", 102 },
    { "Doe", 103 }
};
void Ui_export(size_t* pCount, UserIdentity* pUserIdentities)
{
    // NOTE : If pCount is a valid pointer then we'll set pCount...
    if (pCount) {
        *pCount = gUserIdentites.size();
    }

    // NOTE : If pUserIdentities is a valid pointer then we'll populate it with
    // data...it's the resposibility of the caller to ensure they've correctly
    // gotten the count and have allocated enough storage for the data...
    if (pUserIdentities) {
        size_t i = 0;
        for (const auto& userIdentity : gUserIdentites) {
            // NOTE : Becuase we're getting a C string using the key's c_str()
            //  method we need to make sure that we document cases which will
            //  cause map elements to become invalidated.
            //  The API could be made more robust by having allocators for
            //  dynamic strings, but this would introduce complexity that may
            //  not be necessary.
            pUserIdentities[i].name = userIdentity.first.c_str();
            pUserIdentities[i].id = userIdentity.second;
            ++i;
        }

    }
}
Finally my Delphi attempt part :
Delphi-Quellcode:
Type
UserIdentity = record
    name_ : PAnsiChar;
    id : Integer;
  end;
  PUserIdentity = ^UserIdentity;
procedure Ui_export(pCount : PUInt32; pUserIdentities : PUserIdentity);cdecl; external Cdllname;
....
procedure TForm39.Button24Click(Sender: TObject);
var
  pCount : UInt32;
  LUserEntity : PUserIdentity;
  LUserEntityData : UserIdentity;
  i: Integer;
begin
  Ui_export(@pCount, nil);
  GetMem(LUserEntity, pCount);
  Ui_export(@pCount, LUserEntity);
  for i := 0 to pCount - 1 do
  begin
    memo1.Lines.Add(LUserEntity^.name_+' '+LUserEntity^.id.ToString);
    Inc(LUserEntity);
  end;
end;
The issue with delphi is that i get the 2 first values correctly that's :
Bob
Jone

But for
Alice i get some rubbishes value which is ' yyyyyyyyyyyyyyyyyyyyyyy'

for
Doe
i get it's correct value .

So please is there any incorrect part in my Delphi Implementation ?

Geändert von mandoza (27. Jan 2019 um 23:02 Uhr)
  Mit Zitat antworten Zitat