Writing a dynamic link library that uses the C calling convention is very similar to writing one that uses the PASCAL calling convention (see the floating point documentation). Here is example C code for the C calling convention:
#include <windows.h>
#include <dos.h>
#include "fixdptrs.h"
int FAR PASCAL LibMain (HANDLE hInstance,
WORD wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine)
{
return (1);
}
int FAR PASCAL WEP (int nParameter)
{
return (1);
}
VOID FAR INITFXDPTRSSEG ( smlPosObj, smlNegObj)
struct smallPosObj *smlPosObj;
struct smallNegObj *smlNegObj;
{
plusSmallSeg = FP_SEG( smlPosObj );
minusSmallSeg = FP_SEG( smlNegObj );
}
BOOL FAR ISPSI(recvr)
struct floatObject far *recvr;
{
if (FP_SEG(recvr) == plusSmallSeg)
{return TRUE;}
else
{return FALSE;}
}
short FAR BINARYSUM(high,middle,low)
short high, middle, low;
{
short answer;
answer = 0;
if (high == TRUE) answer = answer + 4;
if (middle == TRUE) answer = answer + 2;
if (low == TRUE) answer = answer + 1;
return answer;
}
You would declare a .def file with these exports:
LIBRARY VWCPRIM
DESCRIPTION 'Example C dynamic link library'
EXETYPE WINDOWS
CODE MOVEABLE DISCARDABLE
DATA MOVEABLE SINGLE
HEAPSIZE 0
EXPORTS WEP @1 RESIDENTNAME
_INITFXDPTRSSEG @2
_ISPSI @3
_BINARYSUM @4
Make the DLL and put it in your system DLL directory. Then in Smalltalk, define a subclass of DynamicLinkLibrary, say TestCDLL, and define the following methods.
!TestCDLL methods!
initialize
"Initialize fixed pointers segments"
self initFxdPtrsSeg: 3 with: -3!
initFxdPtrsSeg: anObject1 with: anObject2
<c: '_INITFXDPTRSSEG' self self none>!
binarySum: high middle: middle low: low
"Test if anObject's class is positive small integer"
<c: '_BINARYSUM' boolean boolean boolean short>!
isPSI: anObject
"Test if anObject's class is positive small integer"
<c: '_ISPSI' self boolean>! !
Open the DLL for Smalltalk by executing:
TestCLibrary := TestCDLL open: 'vwcprim.dll'.
This assigns the handle to TestCLibrary. This must be executed everytime you start up Smalltalk, so you might want to put it in the SystemDictionary method 'startUp'.
Initialize the fixed pointer segments..
TestCLibrary initialize
Try evaluating:
TestCLibrary isPSI: 1
Should be true
TestCLibrary isPSI: -1
Should be false
TestCLibrary binarySum: true middle: true low: false
Should be 6
TestCLibrary binarySum: false middle: true low: true
Should be 3