调用c语言做的DLL,好像有点难度(200分)

  • 主题发起人 主题发起人 dulei_115
  • 开始时间 开始时间
D

dulei_115

Unregistered / Unconfirmed
GUEST, unregistred user!
如何调用下面的c做的一个DLL函数
DLL的c语法说明如下:
int Encrypt(IN long EncAlgID,IN const BYTE * PubKeyOrCert,IN DWORD PubKeyOrCertLen,IN const BYTE * PlanText,IN DWORD PlanTextLen,OUT BYTE * CipherText,IN OUT DWORD * CipherTextLen)

我试了几天了,参数类型改过好几次,效果最好的是这样
project 中 uses ShareMem

TEncrypt = function (EncAlgID: Longint; PubKeyOrCert: PChar;
PubKeyOrCertLen: PLongWord; PlanText: PChar; PlanTextLen: PLongWord;
CipherText: PChar; var CipherTextLen: PLongWord): Integer; stdcall;

传参数时PChar的全部用array[0..255] of char

---------------------------------------------------
可是调用时,有时还是会出现读地址错,有时甚至还会将一些根本不相干的变量(例如某些循环变量、整形变量)值给改了,弄的我头都晕了。我有时怀疑是dll的问题,可是这个dll,人家用c调用没有问题。
 
function UTEncrypt(EncAlgID:Integer;PubKeyOrCert:PByte;PubKeyOrCertLen:DWORD;
PlanText:PByte; PlanTextLen:DWORD; CipherText:PByte;var CipherTextLen:DWORD):Integer;
stdcall;external 'aaa.dll'


procedure TForm1.Button1Click(Sender: TObject);
var
PubKeyOrCert:string;
PlanText:string;
ClipherText:string;
CipherTextLen:DWORD;
begin
PubKeyOrCert:='xyz';
PlanText:='abcdefghijklmnopqrst';
CipherTextLen:=1024;
SetLength(ClipherText,CipherTextLen);
UTEncrypt(0,@PubKeyOrCert[1],Length(PubKeyOrCert),@PlanText[1],Length(PlanText), @ClipherText[1],CipherTextLen);
SetLength(ClipherText,CipherTextLen);
end;
 
dll参数格式不一致,不能用stdcall,改成cdecl试试
 
to smokingroom
现在问题是这样,我觉得它不方便,我自己有把它封装了一次,封装成函数,结果调用成功了,返回的CipherText也正确,
但是我程序里面的一些变量的值却变了,例如:

for i := 0 to n - 1 do
begin
//调用函数,函数形式
//调用过后i和n的值全变了,说明上面的函数完全不关它两个的事
end;
直接写就没事

-----好像我问这个问题之前就是这样,我头昏了,记不清楚了
 
cdecl,safecall之类的都试过了。
 
TEncrypt = function (EncAlgID: Longint; PubKeyOrCert: Byte;
PubKeyOrCertLen: LongWord; PlanText: Byte; PlanTextLen: LongWord;
CipherText: Byte; var CipherTextLen: LongWord): Integer; stdcall;
在使用的时候,传入参数时Byte全部用array [0..255] of Byte,将XX[0]传入.
在调用某些DLL时,如果你要传入100字节的数据,那你数组一定要定义大于100字节,否则会影响程序中的其他变量.
 
Integer不行,它不是标准的类型
 
int Encrypt(IN long EncAlgID,IN const BYTE * PubKeyOrCert,IN DWORD PubKeyOrCertLen,IN const BYTE * PlanText,IN DWORD PlanTextLen,OUT BYTE * CipherText,IN OUT DWORD * CipherTextLen)

function Encrypt(EncAlgID: LongInt; const PubKeyOrCert: array of Byte; PubKeyOrCertLen: Cardinal; const PlanText: array of Byte; PlanTextLen: Cardinal; out CipherText: array of Byte; var CipherTextLen: Cardinal): Integer; stdcall;
 
弄好了,如下:
原始定义:
int Encrypt(IN long EncAlgID,IN const BYTE * PubKeyOrCert,IN DWORD PubKeyOrCertLen,IN const BYTE * PlanText,IN DWORD PlanTextLen,OUT BYTE * CipherText,IN OUT DWORD * CipherTextLen)
------------------------------------
Delphi定义:
TEncrypt = function (EncAlgID: Longint; PubKeyOrCert: PChar;
PubKeyOrCertLen: LongWord; PlanText: PChar; PlanTextLen: LongWord;
CipherText: PChar; CipherTextLen: PLongWord): Integer; cdecl;
--------------------------------------------
调用:
var
...
vErrorCode: Integer;
vPubKey: array[0..127] of Char;
vPubKeyLen: LongWord;
vPlanText: array[0..255] of Char;
vPlanTextLen: LongWord;
vCipherText: array[0..255] of Char;
vCipherTextLen: LongWord;
...
begin
...
vErrorCode := TEncrypt(pProc)(2, @vPubKey[0], vPubKeyLen, @vPlanText[0], vPlanTextLen, @vCipherText[0], @vCipherTextLen);
...
end;
-----------------------------------------------------
先前我也试过将stdcall换成cdecl,但是传参数的时候直接传的arrayofchar,而不是@arrayofchar[0],结果出错,后来改好了又忘了试试cdecl,唉,怪我整个人都给弄晕了。
------------------------------------
谢谢各位了,等会再结贴
 
多人接受答案了。
 

Similar threads

后退
顶部