Ongelma on tämä.
Olen tekemässä ohjelmaa (kieli delphi) joka rakentuu plugineista(dll). Ohjelma sisältää tietokannan jota pluginit voivat käyttää. Tietokanta taas rakentuu yksiköistä (record/struct) jotka sisältävät tarvittavia tietoja esim.
Name: String
Position: TRect
ZOrder: Integer
jne...
Pluginit voivat muuttaa yksiköitten tietoja ulkoisella API.dll kirjastolla esim.
SetPosition(RecAddr: Pointer; Position: TRect)
SetZOrder(RecAddr: Pointer; ZOrder: Integer)
...?
Mutta entä Stringit. TRect ja Integer on helppo nakki koska ne ovat staattisia eli niiden koko ei muutu. Mutta Stringit täytyy olla dynaamisia koska niiden koko saattaa vaihdella huomattavasti.
Käyttöliittymä (API.dll) olisi tarkoitus olla mahdollisimman yksinkertainen, eli pluginien ei ole tarkoitus varata muistia jne.
Mikäli pluginit kirjoitettaisiin vain delphillä homma olisi helppo mutta tarkoitus on että niitä voi kehittää myös muilla kielillä.
Ideoita? Kokemuksia?
Olen tekemässä ohjelmaa (kieli delphi) joka rakentuu plugineista(dll). Ohjelma sisältää tietokannan jota pluginit voivat käyttää. Tietokanta taas rakentuu yksiköistä (record/struct) jotka sisältävät tarvittavia tietoja esim.
Name: String
Position: TRect
ZOrder: Integer
jne...
Pluginit voivat muuttaa yksiköitten tietoja ulkoisella API.dll kirjastolla esim.
SetPosition(RecAddr: Pointer; Position: TRect)
SetZOrder(RecAddr: Pointer; ZOrder: Integer)
...?
Mutta entä Stringit. TRect ja Integer on helppo nakki koska ne ovat staattisia eli niiden koko ei muutu. Mutta Stringit täytyy olla dynaamisia koska niiden koko saattaa vaihdella huomattavasti.
Käyttöliittymä (API.dll) olisi tarkoitus olla mahdollisimman yksinkertainen, eli pluginien ei ole tarkoitus varata muistia jne.
Mikäli pluginit kirjoitettaisiin vain delphillä homma olisi helppo mutta tarkoitus on että niitä voi kehittää myös muilla kielillä.
Ideoita? Kokemuksia?
Vastaukset 3
Vanhimmat
testi
Ilmeisesti a) et halua käyttää:
uses
ShareMem
ja/tai b) plugineja pitää voida tehdä muullakin kuin Delphillä.
Helpoin vaihtoehto:
EI:
Name: String
vaan:
Name: ShortString;
tai:
Name: String[31]; // tai muu sopiva arvo.
{
Tässä siis indeksit 1..31 sisältävät merkkijonon merkit (max. 31 kpl) ja byte(Name[0]) = dynaaminen jonon pituus.
}
Muissa kielissä kuin Delphissä ei yleensä ole suoraa tukea ShortStringeille, mutta ei niiden käsittely muilla kielillä mitenkään mahdotontakaan ole.
Toki voit PChar -tyyppiäkin käyttää, mutta homma menee hankalaksi: sisältöä voi muuttaa, mutta pituutta ei (ainakaan suurempaan suuntaan). Ja pienempäänkin suuntaan muutettaessa on oltava tarkkana muistinkäsittelyn suhteen.
Kolmas mahdollisuus:
type
StrBuf31=Array[0..31] of AnsiChar;
Name: StrBuf31;
Nyky-delphien (Delphi 2 ja uudemmat) string- tyyppiä ei kannata käyttää yli modulirajojen (EXE/DLL), paitsi, jos hyväksyy tuon ShareMemin käytön, ja tekee sekä EXE:n että DLL:n Delphillä.
Mutta tuolla ShortStringillä onnistuu hyvin, jos 255 merkin maksimipituus merkkijonolle ei ole este. Jos on este, niin Array[0..N] of AnsiChar on hyvä vaihtoehto.
ja muille kuin Delphin käyttäjille esim. Str31=String[31] on hyvä dokumentoida näin:
type
Str31=packed record
Len : Byte; // 0..31
Data : Array[1..31] of AnsiChar;
end;
Thanks for the feedback.
Entä jo käyttäisin OleVarianttia.
***********************************************
var
Name: OleVariant;
// Kutsu Dll metodia
MuutaNimi(Name);
// DLL Procedure
procedure MuutaNimi(var nimi: OleVariant);stdcall;
begin
nimi:= 'Nimi on muutettu.';
end;
***********************************************
Tämä toimii ainakin delphillä mutta miten on muut kielet.