MediaWiki:Blocklogentry

From askoh.net wiki

Jump to: navigation, search

Contents

Squeak4.0

Squeak4.0 DLL

  • Open Squeak4.0.sln
  • Right-clicked Squeak4.0, choose Add -> New Item.... Choose Visual C++ -> code -> C++ File(.cpp), and fill name with dll.c.
#include <stdio.h>
#include <string.h>
#include "dll.h"

EXPORT int SqueakInterp(int rcvr, char* selector, int arg) {
	atom = 0;
	return interpret(rcvr, selector, arg, "");
}

EXPORT int SqueakInterp1(int rcvr, char* selector, char* arg){
	atom = 1;
	return interpret(rcvr, selector, -1, arg);
}

EXPORT int SqueakGetFloat(int floatOop, double* floatValue){
	dllFloatValueOf(floatOop, floatValue);
}

EXPORT void SqueakInit(void) {
	squeakMain();
}
  • Right-clicked Squeak4.0, choose Add -> New Item.... Choose Visual C++ -> code -> Header File(.h), and fill name with dll.h.
#ifdef BUILD_DLL
/* DLL export */
#define EXPORT __declspec(dllexport)
#else
/* EXE import */
#define EXPORT __declspec(dllimport)
#endif

int atom;

EXPORT int SqueakInterp(int rcvr, char* selector, int arg);
EXPORT int SqueakInterp1(int rcvr, char* selector, char* arg);
EXPORT int SqueakGetFloat(int floatOop, double floatValue);
EXPORT void SqueakInit(void);
  • Under Configuration Properties -> General -> Configuration Type, set Dynamic Library(.dll).
  • Under C/C++ -> Preprocessor -> Preprocessor Definition, fill in BUILD_DLL;WIN32;_DEBUG;_WINDOWS;__i386__;_CRT_SECURE_NO_DEPRECATE;VM_NAME=\"Squeak\";_USE_32BIT_TIME_T;VM_VERSION=\"SqueakDLL\".
  • interp.c line 715, add these lines
static sqInt* dllMemory[20];
sqInt memCount = 0;
sqInt dllRcvr;
char* dllSelector;
char *dllArgString;
sqInt dllArg;
sqInt interpReturn;
  • interp.c line 4920, add these lines
int dllFloatValueOf(sqInt floatOop, double* floatValue){
	*floatValue = floatValueOf(dllMemory[floatOop]);
}
  • interp.c line 6450-6461, replace these lines with
sqInt interpret(int rcvr, char* selector, int arg, char* argString) {
    sqInt localReturnValue;
    sqInt localReturnContext;
    sqInt localHomeContext;
    char* localSP;
    char* localIP;
    sqInt currentBytecode;

	dllRcvr = rcvr;
	dllSelector = selector;
	dllArgString = argString;
	dllArg = arg;
	interpReturn = 0;
  • interp.c line 8557, add these lines
if(interpReturn)
     return memCount++;
  • interp.c line 21931, add these lines
 sqInt primitiveCString(void) {
    sqInt sz;
    sqInt s;

	//printTop();
	sz = cStringlength();
	s = instantiateClassindexableSize(splObj(ClassString), sz);
	getCStringLength(s + BaseHeaderSize, sz);
	popthenPush(1, s);
}

sqInt primitiveReturnString(void){
    static sqInt temp;

	if ( interpReturn == 0)  {
		interpReturn = 1;
		temp = nilObject();
	}

	temp = dllMemory[memCount]= popStack();
	if(!isIntegerObject(temp))
		addGCRoot(&dllMemory[memCount]);
}


sqInt primitiveRcvrArg(void){
	sqInt rcvrOrArg;
	usqInt oop;

 	rcvrOrArg = integerValueOf(popStack());

	if(rcvrOrArg && (dllArg != -1))
		popthenPush(1, dllMemory[dllArg]);

	else if ((rcvrOrArg == 0) && (dllRcvr != -1))
		popthenPush(1, dllMemory[dllRcvr]);

	else
		popthenPush(1, nilObj);
}
  • sqWin32Window.c line 2518, add these lines
int cStringlength(void)
{
  return lstrlen(dllSelector);
}

int getCStringLength(int cStringIndex, int length)
{
  char *cString= (char *)cStringIndex;
  int count, i;
  char anyString [100];

  strcpy(anyString, dllSelector);
  count = lstrlen(anyString);

  for (i= 0; i < count; i++)
    cString[i]= (char) anyString[i]; /* will remove leading zeros from unicode */

  return count;
}
  • sq.h line 446, add these lines
extern char *dllSelector;
extern char *dllArgString;
  • sqWin32Intel.c line 1194, edit
int squeakMain (HINSTANCE hInst,
  • sqWin32Intel.c line 1211, edit
    GetModuleFileNameW(null, vmNameW, MAX_PATH);
  • sqWin32Intel.c line 1179, comment the line
//    interpret();

MainProgram

  • Create a new empty project named MainProgram. Fill in Location: as "MyRoot\VS2008\Projects". Under Solution:, choose add to solution.
  • Right-clicked MainProgram, choose Add -> New Item.... Choose Visual C++ -> code -> C++ File(.cpp), and fill name with main.c.
#include <windows.h>
#include <stdio.h>

#define sqPtr int

struct point{
	sqPtr sPoint;
	double x;
	double y;
};

struct line {
  sqPtr sline;
  struct point start;
  struct point end;
  double length;
};

char sqExpression[50]= "";

double getFloat(sqPtr floatOop);
void setPoint(struct line *aLine, struct point *aPoint, double x, double y);
void lineNew(struct line *aLine);
void pointNew(struct point *aPoint, int x, int y);
void printPoint(struct point *aPoint);
void printVelocity(struct line *aLine);
void setStartPoint(struct line *aLine, double x, double y);
void setEndPoint(struct line *aLine, double x, double y);
void setVelocity(struct line *aLine, double x, double y);
void getStartPoint(struct line *aLine);
void getEndPoint(struct line *aLine);

int main () {
	typedef void (*pfunc)();
	struct line cline1;

	/*Windows handle*/
	HANDLE hdll;

	/*A pointer to a function*/
	pfunc SqueakInit;
	pfunc SqueakInterp1;
	pfunc SqueakInterp2;

	/*LoadLibrary*/
	hdll = LoadLibrary("Squeak4.0.dll");

	/*GetProcAddress*/
	SqueakInit = (pfunc)GetProcAddress(hdll, "SqueakInit");
	SqueakInterp1 = (pfunc)GetProcAddress(hdll, "SqueakInterp1");
	SqueakInterp2 = (pfunc)GetProcAddress(hdll, "SqueakInterp2");
	

	SqueakInit();
	//create a line
	lineNew(&cline1);
	printPoint(&cline1.start);		//0@0
	printPoint(&cline1.end);		//3@3
	printVelocity(&cline1);			//1@1

	//set start point
	setStartPoint(&cline1, 1.1, 3.3);
	printPoint(&cline1.start);		//1.1@3.3
	printPoint(&cline1.end);		//3@3
	printVelocity(&cline1);			//1@1

	//set velocity
	setVelocity(&cline1, 0.01, 0.03);
	printVelocity(&cline1);			//0.01@0.03

	//move 1.1s
	perform4(cline1.sline, "moveTime:", "1.1");
	printPoint(&cline1.start);		//1.1@3.3
	printPoint(&cline1.end);		//3@3
	printVelocity(&cline1);			//1@1

	getStartPoint(&cline1);
	getEndPoint(&cline1);
	printPoint(&cline1.start);		//1.111@3.311
	printPoint(&cline1.end);		//3.011@3.011

	return 0;
}

sqPtr perform1(char* selector){
	return SqueakInterp( -1, selector, -1);;
}

sqPtr perform2(sqPtr rcvr, char* selector){
	return SqueakInterp(rcvr, selector, -1);
}

sqPtr perform3(sqPtr rcvr, char* selector, sqPtr args){
	return SqueakInterp(rcvr, selector, args);
}

sqPtr perform4(sqPtr rcvr, char* selector, char* args){
	return SqueakInterp1(rcvr, selector, args);
}

void printPoint(struct point *aPoint){
	printf("\nPoint: %f @ %f", aPoint->x, aPoint->y);
}

void getStartPoint(struct line *aLine){
	float x, y;
	sqPtr aPoint;

	aPoint = perform2(aLine->sline, "startPoint");
	aLine->start.x = getFloat(perform2(aPoint, "x"));
	aLine->start.y = getFloat(perform2(aPoint, "y"));
}	

void getEndPoint(struct line *aLine){
	float x, y;
	sqPtr aPoint;

	aPoint = perform2(aLine->sline, "endPoint");
	aLine->end.x = getFloat(perform2(aPoint, "x"));
	aLine->end.y = getFloat(perform2(aPoint, "y"));
}	

void printVelocity(struct line *aLine){
	float x, y;
	sqPtr velocity;

	velocity = perform2(aLine->sline, "velocity");
	x = getFloat(perform2(velocity, "x"));
	y = getFloat(perform2(velocity, "y"));
	printf("\nVelocity: %f @ %f", x, y);
}

void setStartPoint(struct line *aLine, double x, double y){
	//exe side point
	aLine->start.x = x;
	aLine->start.y = y;
	//dll side point
	sprintf(sqExpression, "%f@%f", x, y );
	aLine->start.sPoint = perform1(&sqExpression);
	perform3(aLine->sline, "startPoint:", aLine->start.sPoint);
}

void setEndPoint(struct line *aLine, double x, double y){
	//exe side point
	aLine->end.x = x;
	aLine->end.y = y;
	//dll side point
	sprintf(sqExpression, "%f@%f", x, y );
	aLine->end.sPoint = perform1(&sqExpression);
	perform3(aLine->sline, "endPoint:", aLine->end.sPoint);
}

//set velocity at smalltalk side only.
void setVelocity(struct line *aLine, double x, double y){
	//velocity only stored at dll side
	sprintf(sqExpression, "%f@%f", x, y );
	perform3(aLine->sline, "velocity:", perform1(&sqExpression));
}

double getFloat(sqPtr floatOop){
	double temp;
	SqueakGetFloat(floatOop, &temp);
	return temp;
}

void lineNew(struct line *aLine){

	aLine->sline = perform1("SqLine new");
	setStartPoint(aLine, 0, 0);
	setEndPoint(aLine, 3, 3);
	setVelocity(aLine, 1, 1);
	aLine->length = perform2(aLine->sline, "length");
}

  • Right-click on MainProgram, choose Set as StartUp Project.
  • Right-click on MainProgram, choose Project Dependencies..., check Squeak4.0.

Debug

  • Copy Squeak4.1.changes, Squeak4.1.image and SqueakV41.sources into MyRoot/Debug.
  • Click Debug, choose the correct image file.
  • In Squeak window, open a workspace, execute this once "SqueakDLL initialise" and then execute/debug "SqueakDLL processDLL" for every exe call to dll.
Personal tools
Navigation