在Delphi端,函数参数直接声明为
array of ...
被称为
"open array"
. 编译器使用
2.
参数-指向第一个数组元素和高索引(不是长度!)阵列的。这允许调用代码将静态数组或动态数组传递给同一个参数,编译器将相应地传递数组数据。
但是,你的。NET代码只需要数组的1个参数-指向第一个数组元素的原始指针。这就是为什么你没有正确获得你的输出值。你的
lStream.Size
参数值传递到。NET代码期望第三个参数为,因此
Size
值被误解为内存地址。NET代码写入其输出
pArchivo
值为,因此内存错误。不管怎样,这都无关紧要,因为你正在破坏调用堆栈!你最后推了
4.
参数值,然后
stdcall
上。仅网络侧弹出
3.
您需要更改您的
Funcion
变量,通过以下方式之一:
-
保留
pDataIn
参数声明为
array of Byte
,但删除显式
pInSize
参数
. 让编译器隐式传递它:
Funcion : procedure(pDataIn : array of Byte;
//pInSize : Integer;
var pDocumento : Integer
); stdcall;
然后您必须更改的呼叫
Funcion()
要为
lArBytes
数组,以便编译器将正确的大小值传递给
pSize
SetLength(lArBytes, lStream.Size+1); // <-- +1 here!
lStream.Read(PByte(lArBytes)^, High(lArBytes)); // <-- no +1 here!
...
Funcion(lArBytes{, High(lArBytes)}, lInDocSize);
不用说,这不是直观的,尽管它
应该
-
使用
PByte
(或者只是
Pointer
字节数组
:
Funcion : procedure(pDataIn : PByte; // <-- here
pInSize : Integer;
var pDocumento : Integer
); stdcall;
函数()
要将指针传递给第一个数组元素,并显式传递数组长度,请执行以下操作:
SetLength(lArBytes, lStream.Size); // <-- no +1 here!
lStream.Read(PByte(lArBytes)^, Length(lArBytes)); // <-- or here!
...
Funcion(@lArBytes[0]{or: PByte(lArBytes)}, Length(lArBytes), lInDocSize);
或者,我建议你干脆把你的
lArBytes
完全可变。实际上你并不需要它。自从。NET代码需要一个指向字节数据的原始指针,只需传递
TMemoryStream
procedure TForm1.Button1Click(Sender: TObject);
var
lStream : TMemoryStream;
lInDocSize : Integer;
lHndle : THandle;
Funcion : procedure(pDataIn : Pointer;
pInSize : Integer;
var pDocumento : Integer
); stdcall;
begin
lHndle := LoadLibrary('ClassLibrary1.dll');
if (lHndle <> 0) then
try
Funcion := GetProcAddress(lHndle, 'Funcion');
if Assigned(Funcion) then
begin
lInDocSize := 0;
lStream := TMemoryStream.Create;
try
lStream.LoadFromFile('Document1.PDF');
Funcion(lStream.Memory, lStream.Size, lInDocSize);
finally
lStream.Free;
end;
Label1.Caption := IntToStr(lInDocSize);
end;
finally
FreeLibrary(lHndle);
end;
end;