我想将数据存储在DLL中,并将其引用和大小传递给Delphi程序。
我创建了一个C ++ DLL项目和一个Delphi应用程序项目。然后,我通过LoadLibrary
和显式加载DLL GetProcAddress
。
但是,我无法使用返回的引用访问数据。
以下是源代码:
C ++ DLL被调用者函数:
void __stdcall exportClass::getDataReference(char* data, int* bufferLength)
{
// char* charArray: is member of exportClass
charArray = "Pass this Array of Char By Reference";
data = charArray;
bufferLength = sizeof(charArray) / sizeof(charArray[0]);
}
Delphi呼叫者:
procedure callDllFunction();
var
dynamicCharArray : array of AnsiChar;
pData: PAnsiChar;
length: Integer;
pInt: ^Integer;
begin
pData := @dynamicCharArray[0];
length := 10;
pInt := @length;
explicitDllLoaderClass.callGetDataReference(pData, pInt);
SetLength(dynamicCharArray, length);
end;
此代码中有很多错误。
在C ++方面;
该data
参数传递的值,因此重新分配其价值只会是本地的功能,并在所有不会影响调用者。您需要改为通过引用/指针传递参数。您正在尝试使用bufferLength
参数来执行此操作,但未正确为其分配值。
使用sizeof()
上char*
不会得到你正指向字符串数据的正确长度。请参见查找指针指向的字符串的大小
在Delphi方面:
您没有在为动态数组分配有效载荷之前为其分配任何内存。
您的C ++代码是作为非静态类方法实现的,但是您的Delphi代码并未考虑该方法的隐式this
参数(即Self
Delphi类方法中的参数)。它需要一个对象来调用该方法。
由于编译器的差异,公开跨DLL边界直接访问C ++对象不是一个好主意。您应该将DLL函数重新实现为平面C样式函数。您仍然可以使用您的exportClass
,但只能在内部使用DLL,并且必须在Delphi端对它进行抽象访问。
话虽如此,请尝试以下类似的操作:
// export this
void* __stdcall getExportClassObj()
{
return new exportClass;
}
// export this
void __stdcall freeExportClassObj(void *obj)
{
delete (exportClass*) obj;
}
// export this
void __stdcall getDataReference(void *obj, char* &data, int &bufferLength)
{
((exportClass*)obj)->getDataReference(data, bufferLength);
}
// do not export this
void __stdcall exportClass::getDataReference(char* &data, int &bufferLength)
{
// char* charArray: is member of exportClass
charArray = "Pass this Array of Char By Reference";
data = charArray;
bufferLength = strlen(charArray);
}
type
GetExportClassObjFunc = function: Pointer; stdcall;
FreeExportClassObjProc = procedure(obj: Pointer); stdcall;
GetDataReferenceProc = procedure(obj: Pointer; var data: PAnsiChar; var bufferLength: Integer); stdcall;
getExportClassObj: GetExportClassObjFunc;
freeExportClassObj: FreeExportClassObjProc;
getDataReference: GetDataReferenceProc;
...
procedure callDllFunction();
var
dynamicCharArray : array of AnsiChar;
pData: PAnsiChar;
length: Integer;
Obj; pointer;
begin
Obj := getExportClassObj();
try
getDataReference(Obj, pData, length);
// use pData up to length chars as needed...
SetLength(dynamicCharArray, length);
Move(pData^, PAnsiChar(dynamicCharArray)^, length);
...
finally
freeDataReference(Obj);
end;
end;
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句