Comment utiliser Dll Delphi(avec type PChar) en C#
Voici le Delphi code de la DLL:
library Project2;
uses
SysUtils,
Classes;
{$R *.res}
function SimpleConv(const s: string): string;
var
i: Integer;
begin
Result := '';
for i := 1 to Length(s) do
if Ord(S[i]) < 91 then
Result := Result + S[i];
end;
function MsgEncode(pIn: pchar; InLen: Integer; var pOut: pchar; var OutLen: Integer): Boolean; stdcall;
var
sIn: string;
sOut: string;
begin
SetLength(sIn, InLen);
Move(pIn^, sIn[1], InLen);
sOut := SimpleConv(sIn); //Do something
OutLen := Length(sOut);
GetMem(pOut, OutLen);
Move(sOut[1], pOut^, OutLen);
Result := OutLen > 0;
end;
procedure BlockFree(Buf: pchar); stdcall;
begin
if assigned(Buf) then
FreeMem(Buf);
end;
exports
MsgEncode,
BlockFree;
begin
end.
La fonction de Dll MsgEncode sera allocmem à la moue param, et la BlockFree est utilisée pour libérer la mémoire qui alloced par MsgEncode.
Ma question est: Comment puis-je utiliser cette dll en C#? Je suis un débutant en C#.
Quelle VERSION de Delphi? (Très important)
OriginalL'auteur Leo | 2011-02-23
Vous devez vous connecter pour publier un commentaire.
Je vais prendre votre question à la valeur nominale, avec quelques réserves cependant:
PChar
parce quePChar
flotte entreAnsiChar
etWideChar
selon la version de Delphi. J'ai supposé que vous utilisez Unicode Delphi. Si non, alors vous aurez besoin de changer la chaîne de triage, la valeur de P/Invoke côté.BlockFree
afin qu'il puisse recevoir un pointeur non typé. Il n'y a pas besoin pour cela d'être de types dePChar
, il est juste d'appelerFree
.Voici la modification du code Delphi:
Et voici le code C# de l'autre côté:
Cela devrait vous obtenir a commencé. Puisque vous êtes nouveau à C#, vous allez avoir besoin de faire un peu de lecture sur P/Invoke. Profitez-en!
Vous ne pouvez pas le faire, et ce code ne fait pas ça! Il ne GetMem et FreeMem à Delphes, avec le même tas.
Que puis-je faire si j'utilise Delphi 6 de faire la même fonctionnalité. Essayé la même étape, mais la valeur de la "msg" sera "桔獩椠整瑳". (am à l'aide de Delphi 6 & Visual studio 2010 .net framework 4.0)
Connaissez-vous la différence entre
PAnsiChar
etPWideChar
? EntreAnsiString
etUnicodeString
. EntrePtrToStringAnsi
etPtrToStringUni
?Non, je ne suis pas familer avec PAnsiChar , PWideChar , AnsiString, UnicodeString..etc, suis penchée. veuillez explaing ce que j'ai à faire de même à l'aide de delphi 6.
OriginalL'auteur David Heffernan
Noter que C# chaîne de données est Unicode, donc si vous procédez à cette Delphi code à l'aide de PChar, il sera caché de conversion de PChar à PWideChar effectuée dans le PInvoke appel. (Conversion sens de répartition de l'autre de la mémoire tampon et la copie de toutes les données pour le nouveau tampon) Si vous avez l'intention de ce code Delphi pour être utilisé avec C# et vous vous souciez de la performance, vous devez modifier votre code Delphi pour fonctionner sur PWideChar données.
Il y a une autre raison d'utiliser PWideChar au lieu de PChar: Delphi alloue la OleString type à l'aide de la Win32 SysAllocString allocateur, comme par COM exigences. Cela signifie que le destinataire de la chaîne est capable de libérer à l'aide de l'API Win32.
Si vous n'êtes pas réellement de traitement de texte dans votre fonction, mais sont à l'aide de PChar comme un substitut pour un tableau d'octets arbitraires valeurs, vous pouvez vous en sortir avec ça sur la non géré côté de l'appel, mais pas sur le côté géré. Si c'est le byte de données, il doit être déclarée en tant que tableau de byte pour éviter charset ou char de la taille des conversions.
Sur le C# du côté de la maison, vous aurez besoin d'utiliser PInvoke d'appeler le non géré Delphi fonction de DLL. Voir pinvoke.net pour plus de détails sur la façon d'annoter l'appel en C# pour obtenir PInvoke pour prendre soin de l'allocation de mémoire tampon automatiquement. Trouver une fonction API Win32 qui passe PChar (ou PWideChar) params similaire à votre fonction et de la recherche PInvoke.net pour PInvoke déclaration à utiliser dans du code managé.
Puis toujours à l'aide de PWideChar affectés par le biais de SysAllocString est important.
Avez-vous lu mon P/Invoke réponse qui évite SysAllocString?
large Delphi: après mon temps.
Qu'avez-vous contre SysAllocString? Le code serait beaucoup plus simple, et vous n'aurez pas à l'exportation d'un deallocator.
OriginalL'auteur dthorpe
Édité
Désolé, je n'ai pas vu que vous exportez BlockFree fonction.
La règle de base est: toujours d'allouer et de libérer de la mémoire dans le même module; si vous allouer de la mémoire dans la Dll, il devrait être libéré dans la même Dll.
Donc, si vous libérer de la mémoire avec BlockFree vous allouer et de libérer de la mémoire dans le même module, c'est OK.
Noter que Delphi chaîne et PChar types sont dépendants de la version - ils sont la norme ANSI avant Delphi 2009 et UNICODE dans Delphi 2009 et après.
OriginalL'auteur kludg