从C ++ DLL到Delphi:如何将指向数据的指针从C ++ DLL传递到Delphi程序?

用户名

我想将数据存储在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参数(即SelfDelphi类方法中参数)。它需要一个对象来调用该方法。

由于编译器的差异,公开跨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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章