Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Delphi C++ Dll


Автор: randydom 28.1.2019, 01:34
Hello every one and sorry for not writing my thread in Russian simply because i don't handle it . smile 
I've a C++ DLL that i want to consume from Delphi Project ; My C++ part is
Код

//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 "
Код


#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 : 
Код

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 ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)