我必须在Delphi 6中使用来自外部C DLL的编码函数 . 以下是提供的声明:
long <Function Name> (char *Data, long &Apply, char *ReturnVal, long &Size)
Data是输入值,Apply是布尔值(默认值:FALSE),ReturnVal是DLL的返回值,Size是ReturnVal的长度 .
为了在Delphi 6中使用它,我编写了以下代码:
implementation
const
EncoderDLL = '<DLL NAME>';
FunctionName = 'FUNCTION NAME';
var
_TEST : function(const Data : PChar; Apply : PInteger;stOutput : Pchar;
iSize : PInteger) : integer; stdcall;
.....
.....
var
stInput,stOutput : string;
iLength,i1,iResult : integer;
hnd : THandle;
begin
iLength := 0;
i1 := 0;
stInput := Trim(edtInput.Text);
hnd := SafeLoadLibrary(EncoderDLL);
if hnd > 0 then
begin
@_TEST := GetProcAddress(hnd,FunctionName);
if @_TEST <> nil then
begin
iResult := _TEST(PChar(stInput),@i1,PChar(StOutput),@iLength); // ERROR
end;
end;
FreeLibrary(hnd);
end;
我收到 Access Violation 在'ERROR'作为评论 .
如果我用 string 替换函数声明中的 PChar ,则访问冲突不会出现在同一行 . 在释放图书馆的同时 . 此外,正确填充iLength参数的值 .
任何人都可以提供解决此问题的指示 .
3 回答
在不需要数据之前
'const'
为StOutput分配内存
保持PChar,并在调用之前将StOutput初始化为非空字符串(足够长) .
我假设
ReturnVal
是输出参数(函数填充它) . 您应该在代码中为此字符串保留内存 . 但是你应该保留多少记忆?这些功能有一个共同的模式 . You call the function twice .在 first call 中,您将
ReturnVal
设置为nil
,该函数在Size
参数中填写所需的大小 .然后在
StOutput
缓冲区中保留那么多内存并再次调用该函数 . 这次你得到的结果 .请注意,此功能可能会也可能不会遵循此约定 . 但如果没有,那么实际上没有办法告诉你应该为输出参数保留多少内存 .
需要注意的另一件事是调用约定 . C和C函数默认为
cdecl
,而've shown doesn' t的声明则另有说明 . 你已经在Pascal中声明它为stdcall
. 他们应该匹配 .