Creating C DLLs


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


[top] [index]