Using Visual Prolog DLL's from Microsoft Visual Basic

This directory contains examples of how to use a Dynamic Link Library (DLL) created with Visual Prolog in Microsoft Visual Basic (see Using Visual Prolog DLL’s from other languages for an overview of the examples)

All these examples uses the same Visual Prolog DLL’s that are found in the DLLS directory, so these have to be compiled before any of the examples are compiled and run.

These examples tested with MS Visual Basic 5.0

Notes for Visual Basic

Please read the common notes.

sub - if the predicate does not have a return value, and
function - if the predicate has a return value

Visual Prolog

Visual Basic

integer

Integer

real

Double

long

Long

string

String

Input arguments from Visual Basic application to Visual Prolog DLL must be sent ByVal, and output arguments must be declared in Visual Basic using ByRef keyword.

When you transfer output string variables to VB, then you must use dll_Mark_GStack and dll_ReleaseGStack functions on VB side. For more information please read the common notes.

You should use the ASCIIZ_2_VB_String-(i,o) predicate in Prolog for transfer output string parameter to VB, because MS Visual Basic requires BSTR type of strings.

Example getString with ASCIIZ_2_VB_String predicate :

getString(Out):-

       s(Source),

       ASCIIZ_2_VB_String( Source, Out ). %Convert to BSTR type. Needed for Visual basic

Public Declare Sub getReal Lib <name of DLL> (ByRef OutReal As Double)

Caution

In complex commercial applications we insistently recommend using the following more safe way of getting strings (and other data allocated on Prolog GStack) from Prolog DLLs.

1.       All string arguments in global predicates (Prolog DLL) should be declared with input flow.

2.       VB program should allocate memory for all string arguments by itself. That is, VB should allocate VB memory for a string, which should return data from VIP. Calling a Prolog DLL predicate VB should pass to it the pointer to the memory block allocated for the string that should return a value to VB. In this case, VB should declare passing of this string "ByVal".

3.       The predicate in VIP DLL will receive pointer to the VB memory block allocated for the string that should be returned. It should accomplish the following actions:

a.        The VIP predicate should call mem_markGstack.

b.       The VIP predicate should retrieve the required string.

c.       The VIP predicate should write the string data into the memory block obtained from VB. Notice that the size of the allocated memory block should by enough for this string. For instance, VB can previously request the string size.

d.       The VIP predicate should call mem_ReleaseGstack to free all used GStack. In this case, VB need not have any care about Prolog GStack.

e.        The VIP predicate should return control to the main VB program.

4.       Now VB can access the string data modified by the VIP predicate.

Notice that on this way VB program does not accomplish any handling of Visual Prolog GStack. Therefore, VB need not use dll_Mark_GStack and dll_ReleaseGStack functions. From the other hand, Visual Prolog does not need using ASCIIZ_2_VB_String predicate.

For example:

·          VB can use the following declaration of dll_getString:

Public Declare Sub dll_getString Lib "Dll" (ByVal OutStr As String)

·          Visual Prolog should use the following declaration for the correspondent global predicate (with the input string argument):

dll_getString(string OutStr) - (i) language stdcall

·          VB can use the following call of dll_getString:

OutStr = string(1000, " ") 'String memory allocation for 1000 characters

Call dll_getString(OutStr)

·          Visual Prolog can provide the following clauses for dll_getString:

dll_getString(VB_OutStr):-

       StackMark=mem_MarkGStack(),

       %  Prolog code retrieving "PrologString"

       str_len(PrologString, PrologStrLen),

PrologString_Pointer = cast(POINTER, PrologString),      %required to use movmem()

VB_OutStr_Pointer = cast(POINTER, VB_OutStr),              %required to use movmem()

movmem(PrologString_Pointer,VB_OutStr_Pointer,PrologStrLen),

       mem_ReleaseGStack(StackMark).

The movmem predicate copies the specified PrologStrLen number of bytes from the source location in the program memory pointed by PrologString_Pointer to the new location pointed by VB_OutStr_Pointer. See description of movmem predicate in Visual Prolog Help in topic "PROLOG.LIB Predicates Declared in PDCRUNT.PRE". Domain POINTER = ULONG is declared in TYPES.DOM standard include file.

Examples

NONGUI: Microsoft Visual Basic project uses non-GUI Visual Prolog DLL.

USEVPI: Microsoft Visual Basic project uses a Visual Prolog DLL with VPI.