Writing a source code
.C or .CPP file
#include <windows.h>
#include "first.h"
long __declspec(dllexport) __stdcall foo3(long mylong1, long mylong2,long mylong3)
{
long calc;
calc = (mylong1 + mylong2 + mylong3);
return(calc);
};
short __declspec(dllexport) __stdcall foo4(long arg1, long arg2)
{
short rtn;
if (arg1 > arg2)
rtn = 1;
else
rtn = 0;
if (arg1 == arg2)
rtn = 2;
return(rtn);
};
void __declspec(dllexport) __stdcall foo5(void * p_structure)
{
strFromPB * pb_struct;
pb_struct = (strFromPB *) p_structure;
pb_struct->val1 = pb_struct->val1 - 1;
pb_struct->val2 = pb_struct->val2 + 1;
}
Header File
//Includes functions declarations, variables and structures declaration and //initialization.
long __declspec(dllexport) __stdcall foo3(long mylong1, long
mylong2,long mylong3);
short __declspec(dllexport) __stdcall foo4(long arg1, long arg2);
void __declspec(dllexport) __stdcall foo5(void * strFromPB);
typedef struct mystruct{
long val1;
long val2;
} strFromPB;
.Def file
//"Undecorates " functions names decorated by __stdcall
LIBRARY first.dll
EXPORTS foo3 = _foo3@12
EXPORTS foo4 = _foo4@8
EXPORTS foo5 = _foo5@4
In PowerBuilder
Note: the name of the function used in the declaration section should be the same as exported function name. If the .DEF file was not included within the .DLL, the function will be exported decorated and has to be prototyped decorated as well.
If you are using some third party DLLs and rae not sure how the function you are calling is exported, you can use Exported Function section of Quick View.
//Prototype function call in Local or Global External Functions Declaration section:
FUNCTION Int foo4( long arg1, long arg2) Library"d:\API CALLS\first.dll"
FUNCTION Long foo3( long arg1, long arg2, long arg3)Library"d:\API CALLS\first.dll"
SUBROUTINE foo5(ref mystruct struct2)LIBRARY"d:\API CALLS\first.dll"
// Calling function foo4()
Integer li_rtn
Long ll_arg1, ll_arg2
ll_arg1 = Long(sle_arg1.text)
ll_arg2 = Long(sle_arg2.text)
li_rtn = foo4(ll_arg1, ll_arg2)
st_result.text = String(li_rtn)
//Calling function foo3()
Long ll_arg1, ll_arg2, ll_arg3, ll_rtn
ll_arg1 = Long(sle_arg1.text)
ll_arg2 = Long(sle_arg2.text)
ll_arg3 = Long(sle_arg3.text)
ll_rtn = foo3(ll_arg1, ll_arg2, ll_arg3)
st_result.text = String(ll_rtn)
To call subroutine foo5(), which takes a structure by reference as a parameter, create a structure:
mystruct val1 long
val2 long
//Calling subrutine foo5 from PowerBuilder
mystruct pb_struct //Instanciate mystruct
pb_struct.val1 = long(sle_3.text)
pb_struct.val2 = long(sle_4.text)
foo5(pb_struct)
//Display results of subroutine calculations
sle_3.text = string(pb_struct.val1)
sle_4.text = string(pb_struct.val2)
Setting the Byte Alignment on MSVC++
Microsoft compilers provides two methods to specify structure packing: a command-line option (/Zp) and a pragma (pack).
When the compiler packs a structure, it aligns the elements of the structure on a 1-, 2-, or 4-byte boundary in memory.
An application can use packing for indexing purposes or to decrease processor access time.
Unless an application specifies a different value, the default structure packing value is two.
The field size and packing value determine the amount of padding required before a field appears in the structure.
The padding can change the offset of a particular member of the structure.
The compiler calculates each offset of a structure member relative to zero (0). The compiler compares the size of each member to the packing value (which is also known as the alignment value). The compiler aligns the element on the boundary of the smaller of the field size and the packing value.
Finally, the compiler can pad the entire structure to properly align arrays of structures. The compiler






