Reputation: 2201
I have an external function like this:
extern "C" __declspec(dllexport) int __cdecl Identify(BSTR* bstrTemplates, __int64 lCount, __int64* lIndex, __int64* lRetCode)
The bstrTemplates should be a string array.
How should my function look like in D7, and how to pass a string array to the external function. Can't get my head around right now.
Upvotes: 3
Views: 3398
Reputation: 2201
Finally solved the problem. It was the dynamic array. Looks like it can't be used as C-style array. Looks like the length prefix confused the c dll. For the records here the prototype and usage:
Type
type
TArrayOfWideString= array[0..999] of WideString;
Declaration
function Identify(var ATemplates: TArrayOfWideString; ATemplatesCount: int64; var ATemplateIndex: int64; var ARetCode: int64): Integer; cdecl; external 'Identify.dll';
Usage
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);
Upvotes: 2
Reputation: 7330
BSTR* is a pointer to a BSTR (in Delphi BSTR is a WideString).
EDIT: To make the answer complete (and make Rob Kennedy happy :-) ):
Most literal translation:
function Identify(bstrTemplates: PWideString; lCount: int64; lIndex: PInt64; lRetCode: PInt64): Integer; cdecl external 'mydll.dll';
or more the Delphi way:
function Identify(bstrTemplates: PWideString; lCount: int64; var lIndex: Int64; var lRetCode: Int64): Integer; cdecl external 'mydll.dll';
or even (but this depends if the bstrTemplates can be nil):
function Identify(var bstrTemplates: WideString; lCount: int64; var lIndex: Int64; var lRetCode: Int64): Integer; cdecl external 'mydll.dll';
Use the first element in the array when you pass bstrTemplates (eg @MyArray[0])
Upvotes: 1
Reputation: 391336
A BSTR is a WideString in Delphi, and a pointer to a BSTR is also a pointer to a WideString in Delphi, but in terms of C-code, it is most likely an array reference. A typical way to handle such arrays, and I'm going to assume this is how it's done here, is to use a null-terminated array.
So, we need to declare an array of WideString's in Delphi, and leave the last element as null, or nil
in 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
I'm not guaranteeing this will work. I'm guessing here, and haven't tried it (which would involve creating a C project and testing) so this might fail horribly. Worth a shot though.
Upvotes: 3