# -*- coding: utf-8 -*-
import os,os.path,sys,ctypes,time
class tcc(object):
# Valeur par défaut à adapter à l'installation
tccplace="tcc"
def __init__(self, nom="tccinpy", source="", tccplace=None):
import ctypes
self.source=source
self.dllname=nom
self.dll=None
if tccplace is None:
self.tccplace=tcc.tccplace
else:
self.tccplace=tccplace
if not os.path.isfile(self.tccplace+'\\dll_squ.c'):
open(self.tccplace+'\\dll_squ.c',"w").write('''
#include <windows.h>
#include <memory.h>
#include <string.h>
#include <wchar.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#define DLL_EXPORT __declspec(dllexport)
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
// chargement de la DLL
case DLL_PROCESS_ATTACH:
break;
// attachement d'un processus
case DLL_THREAD_ATTACH:
break;
// détachement d'un processus
case DLL_THREAD_DETACH:
break;
// déchargement de la DLL
case DLL_PROCESS_DETACH:
//détachement du processus
break;
default:
break;
}
return TRUE;
UNREFERENCED_PARAMETER(hinstDLL);
UNREFERENCED_PARAMETER(lpvReserved);
}
%SOURCE%
''')
if source != "":
self.setsource(source)
def setsource(self, source=""):
self.source=source
self.compile()
def compile(self):
import ctypes,os,os.path,shutil,time,subprocess
if os.path.isfile(self.tccplace+'\\TEMP_INTERNE.dll'):
os.remove(self.tccplace+'\\TEMP_INTERNE.dll')
scode=open(self.tccplace+"\\dll_squ.c","rb").read()
self.source = self.source.replace("PUBLIQUE","DLL_EXPORT __stdcall ")
if self.source.find("DLL_EXPORT __stdcall ")>-1:
scode = scode.replace("%SOURCE%",self.source)
else:
scode = scode.replace("%SOURCE%","DLL_EXPORT __stdcall "+self.source)
open(self.tccplace+"\\TEMP_INTERNE.c","wb").write(scode)
bufdir=os.getcwd()
os.chdir(self.tccplace)
pipe = subprocess.Popen("tcc -shared -o TEMP_INTERNE.dll TEMP_INTERNE.c", shell=True, stderr=subprocess.PIPE).stderr
result=pipe.readlines()
os.chdir(bufdir)
if len(result)>0:
print "\r\n".join(result)
print u"ERREUR ; la DLL n'a pas été créée."
raise WindowsError
return
if os.path.isfile(self.tccplace+'\\TEMP_INTERNE.dll'):
shutil.copyfile(self.tccplace+'\\TEMP_INTERNE.dll', os.getcwd()+'\\'+self.dllname+'.dll')
self.dll=ctypes.windll.LoadLibrary(self.dllname)
else:
self.dll=None
print u"ERREUR ; la DLL n'a pas été créée."
raise WindowsError
if __name__=='__main__':
c=tcc(nom='test1', source='''PUBLIQUE int test(int a,int b) {
int r;
r=a*b;
return r;
}
PUBLIQUE int testadd(int a,int b) {
int r;
r=a+b;
return r;
}
''')
print c.dll.test(3,4)
print c.dll.test(33,44)
print c.dll.testadd(33333,44444)
print
c=tcc(nom='test2', source='''int stest(char *st) {
st[2]=(char)'-';
st[3]=(char)'x';
st[4]=(char)'y';
st[5]=(char)'z';
st[6]=(char)'-';
return strlen(st);
}
''')
ss="ABCDEFGHI"
stemp=ctypes.create_string_buffer(ss)
print c.dll.stest( stemp)
print ss
print stemp.value
print
c=tcc(nom='test3', source='''int longuni(wchar_t *t) {
int i = 0;
while(t[i] != '\\0') {
i++;
}
return i;
}
PUBLIQUE int utest(wchar_t *st) {
st[5] = (wchar_t) '_';
st[6] = 0x20AC; //caractère Euro
€
st[7] = (wchar_t) '_';
return longuni(st);
}
''')
ss=u"ééABCDEFGHIèè"
stemp=ctypes.create_unicode_buffer(ss)
print c.dll.utest(stemp)
print ss
print stemp.value.encode('cp1252','replace')
print
c=tcc(nom='test4', source='''float dtest(float i) {
float j=i*2.0;
return j;
}
''')
c.dll.dtest.restype = ctypes.c_float
ctemp=c.dll.dtest(ctypes.c_float(222.333))
print ctemp
print
c=tcc(nom='test5', source='''char* sttest(char *s) {
char *toto=s;
strcat(toto,"1234");
return toto;
}
''')
c.dll.sttest.restype = ctypes.c_char_p
ctemp=c.dll.sttest("ABCD")
print ctemp
print