我有一个外部函数是这样的:如何将字符串数组传递给外部DLL?
extern "C" __declspec(dllexport) int __cdecl Identify(BSTR* bstrTemplates, __int64 lCount, __int64* lIndex, __int64* lRetCode)
的bstrTemplates应该是一个字符串数组。
我的函数应该如何在D7中看起来像以及如何将字符串数组传递给外部函数。现在无法让我的头转向。
我有一个外部函数是这样的:如何将字符串数组传递给外部DLL?
extern "C" __declspec(dllexport) int __cdecl Identify(BSTR* bstrTemplates, __int64 lCount, __int64* lIndex, __int64* lRetCode)
的bstrTemplates应该是一个字符串数组。
我的函数应该如何在D7中看起来像以及如何将字符串数组传递给外部函数。现在无法让我的头转向。
终于解决了这个问题。这是动态数组。看起来它不能用作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);
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])
你的答案有点混乱。 BSTR是Delphi中的WideString。指向BSTR的指针与WideString不同。我想这就是你想说的,但它不是这样的,至少不是我。 “哪个”在这里指向“正在被讨论的东西”,这是“指向BSTR的指针”。指向BSTR的指针与指向序列中第一个BSTR的指针基本相同。我猜数组是空终止的。 – 2010-07-27 11:18:26
@Lasse:是的,我打算说在Delphi中BSTR是一个WideString(为了清楚起见,我稍微改了一些文字,谢谢) – Remko 2010-07-27 11:30:41
-1。你所说的是真的。但那又如何? – 2010-07-27 15:09:50
甲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项目和测试),所以这可能会失败可怕。值得一枪,但。
是的,对于一个动态数组总是传递一个指向第一个元素的指针,因为你也可以对静态数组执行此操作,所以将数组传递给c(++)dll的(+1) – Remko 2010-07-27 11:31:46
好了。第一眼看起来很有意义。但是有两个怪癖。将nil分配给模板[2]不起作用。编译器告诉我WideString和指针是不兼容的类型。因此,将长度设置为3并保留模板[2],如果我将该数组传递给该函数,则会给我一个访问冲突。 – pantarhei 2010-07-27 11:50:22
你不能将nil分配给WideString(但你可以指定空字符串''),但我认为lCount参数可能指示数组中的元素数量?所以在这个例子中,你也要做SetLength(..,2)。 – Remko 2010-07-27 12:37:38
同样的问题:http://www.delphipraxis.net/153261 -string-array-als-parameter-fuer-externe-dll.html#post1037847 – Remko 2010-07-28 07:33:28
确实。这是我在德国论坛的问题。 – pantarhei 2010-07-28 08:58:18