Change the definition of _MyStruct::name to const char *, and just assign the literal to it.
Note that names starting _ followed by an uppercase letter are reserved for the implementation, so your whole program has undefined behaviour.
You don't need to typedef struct.
struct MyStruct
{
const char* name; // mutable pointer to constant char(s)
// other fields
};
using PMyStruct = * MyStruct;
extern "C" __declspec(dllexport) __cdecl void MyTestStr(PMyStruct pMyStruct)
{
pMyStruct->name = "string";
}
In the general case, it is inadvisable to pass owning pointers across dll boundaries. Instead the caller should allocate, and the function copy into that allocation. This is the pattern used across the Win32Api. You either return the size, or take int * parameters to write the sizes into
C++ Dll
extern "C" __declspec(dllexport) __cdecl void MyTestStr(PMyStruct pMyStruct = nullptr, int * firstname_size = nullptr, int * lastname_size = nullptr)
{
if (pMyStruct)
{
std::strncpy(pMyStruct->firstname, "string", pMyStruct->firstname_len);
std::strncpy(pMyStruct->lastname, "other string", pMyStruct->lastname_len);
}
if (firstname_size) { *firstname_size = 7; }
if (lastname_size) { *lastname_size = 13; }
}
Delphi exe
type
PInteger = ^Integer;
PMyStruct = ^MyStruct;
MyStruct= record
firstname : PAnsiChar;
firstname_len : Integer;
lastname : PAnsiChar;
lastname_len : Integer;
// other fields
end;
procedure MyTestStr(pMyStruct: PMyStruct; firstname_len : PInteger; lastname_len : PInteger); cdecl; external 'mytest.dll' name 'MyTestStr';
procedure TestMyRec();
var
myStruct: MyStruct;
begin
// If you don't know how much memory you will need, you have to ask
MyTestStr(nil, @myStruct.firstname_len, @myStruct.lastname_len);
GetMem(myStruct.firstname, myStruct.firstname_len);
GetMem(myStruct.lastname, myStruct.lastname_len);
MyTestStr(@myStruct);
// Use myStruct
FreeMem(myStruct.firstname);
FreeMem(myStruct.lastname);
end;
Tokyoversion .