Ich habe mir den Code gerade mal ein wenig angeguckt und ein paar Modifikationen vorgenommen, damit man auch Befehle an MWconn richten kann.
Fangen wir an bei der DLL. Folgenden Code habe ich ergänzt:
Code: Alles auswählen
function MWconn_GetCommand(var AStringPointer: PChar; AStringLength : Integer) : Integer; stdcall; export;
begin
Result := - 1;
// check if IPC is open
if (vBufferB <> nil) then
begin
// check if we have read access
if (vAccessMode <> mwamNone) then
begin
try
if (AStringLength > Length(vBufferB^.Command)) then
AStringLength := Length(vBufferB^.Command);
// copy data from answer buffer
Move(vBufferB^.Command, AStringPointer, AStringLength);
Result := AStringLength;
except
end;
end;
end;
end;
function MWconn_SetCommand(var AStringPointer: PChar; AStringLength : Integer) : Boolean; stdcall; export;
begin
Result := false;
// check if IPC is open
if (vBufferB <> nil) then
begin
// check if we have write access
if ((vAccessMode = mwamWrite) or (vAccessMode = mwamAll)) then
begin
try
// prevent buffer overflow
if (AStringLength < Length(vBufferB^.Command)) then
begin
// copy data to command buffer
Move(AStringPointer, vBufferB^.Command, AStringLength);
vBufferB^.Command[AStringLength] := #0;
Result := true;
end;
except
end;
end;
end;
end;
function MWconn_Answer(var AStringPointer: PChar; AStringLength : Integer) : Integer; stdcall; export;
begin
Result := - 1;
// check if IPC is open
if (vBufferB <> nil) then
begin
// check if we have read access
if (vAccessMode <> mwamNone) then
begin
try
if (AStringLength > Length(vBufferB^.Answer)) then
AStringLength := Length(vBufferB^.Answer);
// copy data from answer buffer
Move(vBufferB^.Answer, AStringPointer, AStringLength);
Result := AStringLength;
except
end;
end;
end;
end;
Zudem muss die
exports-Klausel erweitert werden:
Code: Alles auswählen
exports
[...]
MWconn_GetCommand,
MWconn_SetCommand,
MWconn_Answer;
Danach fehlt nur noch das Wrapping in der
Mw.net.cs.
Der Import der Methoden:
Code: Alles auswählen
[DllImport("MWconnIO.dll")]
private static extern int MWconn_GetCommand(ref string Command, int iStrLen);
[DllImport("MWconnIO.dll")]
private static extern bool MWconn_SetCommand(ref string Command, int iStrLen);
[DllImport("MWconnIO.dll")]
private static extern int MWconn_Answer(ref string Answer, int iStrLen);
Die Definition der Property-Handler:
Code: Alles auswählen
/// <summary>
/// Einen Befehl ausführen lassen
/// </summary>
public string Command
{
get
{
return GetCommandVar();
}
set
{
SetCommandVar(value);
}
}
/// <summary>
/// Die Antwort zu einem ausgeführten Befehl
/// </summary>
public string Answer
{
get
{
return AnswerVar();
}
}
Die Erweiterung des "String-Hacks" (die Answer kann bis zu 600 Zeichen lang sein):
Code: Alles auswählen
// Hacks um Strings aus der Pascal-DLL herauszubekommen
int maxLen = 768;// 256;
Und schlussendlich die Hilfsmethoden:
Code: Alles auswählen
private string GetCommandVar()
{
string GetCommandVar_Temp = new string(' ', maxLen);
MWconn_GetCommand(ref GetCommandVar_Temp, maxLen);
return GetCommandVar_Temp;
}
private bool SetCommandVar(string ACommand)
{
return MWconn_SetCommand(ref ACommand, ACommand.Length);
}
private string AnswerVar()
{
string AnswerVar_Temp = new string(' ', maxLen);
MWconn_Answer(ref AnswerVar_Temp, maxLen);
return AnswerVar_Temp;
}
Wäre nett, wenn das ganze jemand mal testen könnte. Ich konnte zwar testhalber die DLL kompilieren, um Syntaxfehler auszuschließen, allerdings fehlt mir hier zur Zeit die .NET-Umgebung, um auch den C#-Code überprüfen zu können.
Wenn man übrigens in der DLL alle Windows.CopyMemory() durch SysUtils.Move() ersetzt und die Windows-Unit und die Classes-Unit aus der
uses-Klausur rausschmeißt, halbiert sich die Größe der DLL...
cheers...