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 ?