如何将字符串数组传递给外部DLL?

时间:2010-07-27 09:42:07

标签: delphi

我有一个像这样的外部函数:

extern "C" __declspec(dllexport) int __cdecl Identify(BSTR* bstrTemplates, __int64 lCount, __int64* lIndex, __int64* lRetCode) 

bstrTemplates应该是一个字符串数组。

我的函数在D7中应该是什么样的,以及如何将字符串数组传递给外部函数。现在无法理解我的想法。

3 个答案:

答案 0 :(得分:3)

BSTR是Delphi中的WideString,指向BSTR的指针也是Delphi中指向WideString的指针,但就C代码而言,它很可能是数组引用。处理这种数组的一种典型方法,我将假设这是在这里完成的,是使用以null结尾的数组。

所以,我们需要在Delphi中声明一个WideString数组,并将最后一个元素保留为null,或者在Delphi中保留nil

var
  templates : array of WideString;
begin
  SetLength(templates, 3); // 2 template names + 1 nil
  templates[0] := 'template1';
  templates[1] := 'template2';
  templates[2] := nil;

  Identify(@templates[0], ....); // pass it as a pointer to the first element

我不保证这会起作用。我猜这里,并没有尝试过(这将涉及创建一个C项目和测试)所以这可能会失败。值得一试。

答案 1 :(得分:2)

终于解决了这个问题。这是动态阵列。看起来它不能用作C风格的数组。看起来长度前缀混淆了c dll。对于这里的记录原型和用法:

类型

type
  TArrayOfWideString= array[0..999] of WideString;

声明

function Identify(var ATemplates: TArrayOfWideString; ATemplatesCount: int64; var ATemplateIndex: int64; var ARetCode: int64): Integer; cdecl; external 'Identify.dll';

用法

var
  templateIndex, retCode: int64;
  templates: TArrayOfWideString;
  retval: integer;

//TODO: range checking for TArrayOfWideString needed

templates[0] := 'template1';
templates[1] := 'template2';

retVal := Identify(templates, 2, scanIndex, retCode);

答案 2 :(得分:1)

BSTR *是指向BSTR的指针(在Delphi BSTR中是一个WideString)。

编辑:为了完成答案(让Rob Kennedy高兴:-)):

大多数字面翻译:

function Identify(bstrTemplates: PWideString; lCount: int64; lIndex: PInt64; lRetCode: PInt64): Integer; cdecl external 'mydll.dll';

或更多Delphi方式:

function Identify(bstrTemplates: PWideString; lCount: int64; var lIndex: Int64; var lRetCode: Int64): Integer; cdecl external 'mydll.dll';

或甚至(但这取决于bstrTemplates是否为零):

function Identify(var bstrTemplates: WideString; lCount: int64; var lIndex: Int64; var lRetCode: Int64): Integer; cdecl external 'mydll.dll';

传递bstrTemplates时使用数组中的第一个元素(例如@MyArray [0])