Измените определение _MyStruct::name
на const char *
и просто присвойте ему литерал.
Обратите внимание, что имена, начинающиеся с _
, за которыми следует заглавная буква, зарезервированы для реализации, поэтому все вашеПрограмма имеет неопределенное поведение.
Вам не нужно 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";
}
В общем случае нежелательно передавать указатели-владельцы через границы dll.Вместо этого вызывающий должен выделить , и функция скопирует в это распределение.Это шаблон, используемый в Win32Api.Вы либо возвращаете размер, либо берете int *
параметры, чтобы записать размеры в
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;