Hello every one and sorry for not writing my thread in Russian simply because i don't handle it . 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 : BobJoneBut for Alice i get some rubbishes value which is ' yyyyyyyyyyyyyyyyyyyyyyy' for Doei get it's correct value . So please is there any incorrect part in my Delphi Implementation ?
|