2010-07-27 85 views
3

我有一个外部函数是这样的:如何将字符串数组传递给外部DLL?

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

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

我的函数应该如何在D7中看起来像以及如何将字符串数组传递给外部函数。现在无法让我的头转向。

+0

同样的问题:http://www.delphipraxis.net/153261 -string-array-als-parameter-fuer-externe-dll.html#post1037847 – Remko 2010-07-28 07:33:28

+0

确实。这是我在德国论坛的问题。 – pantarhei 2010-07-28 08:58:18

回答

1

终于解决了这个问题。这是动态数组。看起来它不能用作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); 
1

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

编辑:为了使答案完整(并罗伯肯尼迪开心:-)):

最直译:

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

以上的德尔福方式:

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])

+0

你的答案有点混乱。 BSTR是Delphi中的WideString。指向BSTR的指针与WideString不同。我想这就是你想说的,但它不是这样的,至少不是我。 “哪个”在这里指向“正在被讨论的东西”,这是“指向BSTR的指针”。指向BSTR的指针与指向序列中第一个BSTR的指针基本相同。我猜数组是空终止的。 – 2010-07-27 11:18:26

+1

@Lasse:是的,我打算说在Delphi中BSTR是一个WideString(为了清楚起见,我稍微改了一些文字,谢谢) – Remko 2010-07-27 11:30:41

+0

-1。你所说的是真的。但那又如何? – 2010-07-27 15:09:50

3

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

因此,我们需要声明WideString的在德尔福的数组,并留下最后一个元素为空,或者nil在Delphi:

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项目和测试),所以这可能会失败可怕。值得一枪,但。

+0

是的,对于一个动态数组总是传递一个指向第一个元素的指针,因为你也可以对静态数组执行此操作,所以将数组传递给c(++)dll的(+1) – Remko 2010-07-27 11:31:46

+0

好了。第一眼看起来很有意义。但是有两个怪癖。将nil分配给模板[2]不起作用。编译器告诉我WideString和指针是不兼容的类型。因此,将长度设置为3并保留模板[2],如果我将该数组传递给该函数,则会给我一个访问冲突。 – pantarhei 2010-07-27 11:50:22

+0

你不能将nil分配给WideString(但你可以指定空字符串''),但我认为lCount参数可能指示数组中的元素数量?所以在这个例子中,你也要做SetLength(..,2)。 – Remko 2010-07-27 12:37:38

相关问题