Re: DLL with string params callable via D4 and VB

From: Peter Below (TeamB) (100113.1101_at_compuXXserve.com)
Date: 12/13/03


Date: Sat, 13 Dec 2003 20:19:09 +0100

In article <3fdb0650$1@newsgroups.borland.com>, John Remy wrote:
> I have a DLL written in D6 that uses ShortStrings as parameters. We did
> this to avoid the use of Sharemem. I have no problem with other
> D6 apps that call this DLL, however I've having difficulty with a legacy
> app written in D4. This D4 app calls the DLL methods in the same way
> and declares the parameters as shortstrings. I'm obviously doing
> something
> wrong because the value that I pass into the DLL function gets trashed.

Check the declarations of the exported functions on both sides of the fence.
Are they using the same calling convention? You should use stdcall here, by
the way. It is the only calling convention VB knows about.

> One of the D6 functions returns a shortstring and when I try calling this
> within
> D4 the program bombs with an access violation.

Same issue probably: calling convention. Using a shortstring as function
return value should work across Delphi modules, but it would be completely
incompatible with VB. Even using a Shortstring as parameter (as Var or Const,
pass by reference) would be problematic for VB, it would require special
coding on the VB side since it is incompatible with any of the native VB
string types.
 
> Ultimately, I need to call the functions in this D6 DLL within a VB
> project. I haven't even tried that yet! I can't get beyond Delphi to
> Delphi never mind VB to Delphi.
>
> Is there any guidance you could give in regards to passing string
> values into a DLL function (and return values) that would be
> compatible with D4 and VB?

<quote
source="http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19374
">
Delphi DLLS for VB

<< I wonder if there is some examples on how DLLs should be
written in order to be used by EXCEL 97 VBA. >>
 
I think there is a whitepaper on the subject somewhere on the inprise
website but i cannot give you an exact title or location, sorry.
 
The rules are simple:
 
 - declare all exported routines using the stdcall calling convention
 - use Longint for integer types on the Delphi side, Long on the VBA side,
   don't assume that generic types like "Integer" will be the same size
   on both sides of the fence!
 - do not use Pascal Strings at all in parameter lists or return types.
   Use PChar parameters to transfer character data, VBA can pass those
   using ByVal someString$ parameters. You also have to use these type
   of parameters to return strings from the DLL to VBA. In this case the
   VBA side has to provide the memory, see below for an example.
 - Do never return a Pchar as a function result.
 - ByRef parameters on the VBA side are equivalent to Var parameters on
   the Delphi side (ByRef is the default on VBA). ByVal parameters are
   pass-by-value.
   
Passing records can be a bit tricky, especially if they contain string
fields. Always pass records ByRef. You may need to declare them as packed
record on the Delphi side (i don't know if/how VBA packs record types).
Arrays are another problem data type. Arrays of strings are a lost cause,
for others you can declare a matching array type on the Delphi side and a
Var parameter of this type in the parameter list. On the VBA side you
declare this parameter as a ByRef parameter of the arrays element type and
you pass the first array element to it. This avoids some tricky problems
having to do with the implementation of VBA arrays. If the array size can
vary dynamically you must pass the actual size as well so the Delphi side
can figure out how many elements the array actually contains.
 
Here the example re string passing:
 
 With respect to VB this means: the buffer parameter is declared as
 ByVal Buf$, followed by a ByVal maxlen As Long for the buffer size. The
 passed buffer is either a fixed length string (declared as String *
 maxlen) or a normal String filled to the required length with some
 character. The Delphi side declares the Buf parameter as PChar and uses
 the StrLCopy or StrPLCopy function to copy characters into it.
 
Procedure SimpleString(Buf : PChar; maxlen: LongInt);export;stdcall;
 begin
   StrLCopy(Buf, 'Hi There', maxlen-1); //-1 because of terminating #0
 end;
 
Declare Sub SimpleString lib "(dll name in here)" (ByVal lpBuf as String,
ByVal MaxLen As Long)
 
 
Dim MyString as String * 128
 
  SimpleString(MyString, 128)
 
Additional byVal String parameters can be used to pass strings into the DLL
for processing.

</quote>

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


Relevant Pages

  • Re: DLL with string params callable via D4 and VB
    ... I can't get beyond Delphi ... >> Is there any guidance you could give in regards to passing string ... > - use Longint for integer types on the Delphi side, Long on the VBA side, ... > Arrays are another problem data type. ...
    (borland.public.delphi.language.objectpascal)
  • Re: Passing arguments from VBA to DLL
    ... I would assume it has to do with how VBA sends the string to your DLL. ... in a VBA function gives lstrlenAequal to 6. ...
    (microsoft.public.excel.programming)
  • Re: Using function with PChar data type
    ... the author of DLL just ... short STRING into a HUGE string. ... those string type into C like pointer strings. ... I tried to figure out why I could not get basic delphi pascal DLL to ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Passing parameters in VB to a DLL issues
    ... a stack imbalance in calling a DLL function... ... ByVal Name As String) As Long ... in my vba code, i would always receive a lng1 value of 0, ... I have been doing VBA work for a while, ...
    (comp.lang.basic.visual.misc)
  • Re: Using function with PChar data type
    ... DELPHI DLL I was using was just copying to a null terminated string ... But I was leery with the initializing and not allocating space for it. ... I was able to finally get the Delphi DLL to import and marshall correctly. ...
    (microsoft.public.dotnet.languages.vb)