ctypes-commit Mailing List for ctypes (Page 94)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2004-09-03 07:33:08
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30918 Added Files: inc2py.py Log Message: Improved h2py script - still to be refactored and converted into a command line tool. --- NEW FILE: inc2py.py --- # A script which parses C header files, translates #define statements # into Python code. # # Requires that gccxml from http://www.gccxml.org/ is installed and on # the PATH. # # Inspired and partly derived from Python's tools/scripts/h2py.py, but # the include files are passed to a real C preprocessor first, which # then dumps out the #defines to be translated and executed by this script. # # This script generates: # - valid Python code, which can be written to a file and imported # as Python module later, # - a dictionary containing the results of evaluating all the generated # Python expressions # Here are some comments from the h2py script: # # Read #define's and translate to Python code. # Handle #define macros with one argument. # Anything that isn't recognized or doesn't translate into valid # Python is ignored. # By passing one or more options of the form "-i regular_expression" # you can specify additional strings to be ignored. This is useful # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'". # XXX To do: # - turn C Boolean operators "&& || !" into Python "and or not" # - what to do about macros with multiple parameters? import sys, re, os, tempfile import warnings warnings.filterwarnings("ignore", category=FutureWarning) # regular expressions to find #define's p_define = re.compile('^#define[\t ]+([a-zA-Z0-9_]+)[\t ]+') p_macro = re.compile( '^#define[\t ]+' '([a-zA-Z0-9_]+)\(([_a-zA-Z][_a-zA-Z0-9]*)\)[\t ]+') # patterns to replace by a single blank (platform specific) if sys.platform == "win32": # ignore type casts. Sounds strange, but works. ignores = r""" \(\s*HRESULT\s*\) \(\s*BYTE\s*\) \(\s*WCHAR\s*\) \(\s*WORD\s*\) \(\s*USHORT\s*\) \(\s*SHORT\s*\) \(\s*DWORD\s*\) \(\s*UINT\s*\) \(\s*INT\s*\) \(\s*ULONG\s*\) \(\s*LONG\s*\) \(\s*BYTE\s*\) \(\s*LPSTR\s*\) \(\s*LPTSTR\s*\) \(\s*LPWSTR\s*\) \(\s*HKEY\s*\) \(\s*MCIDEVICEID\s*\) \(\s*HANDLE\s*\) \(\s*HWND\s*\) \(\s*HCURSOR\s*\) \(\s*HICON\s*\) \(\s*HDDEDATA\s*\) \(\s*int\s*\) \(\s*u_long\s*\) \(\s*unsigned\s*long\s*\) """ else: ignores = [] ignores = map(re.compile, ignores.strip().splitlines()) # a sequence of pattern / replacement pairs for macro bodies, # passed to re.sub replaces = [ # Remove the U suffix from decimal constants (re.compile(r"(\d+)U"), r"\1"), # Remove the U suffix from hex constants (re.compile(r"(0[xX][0-9a-fA-F]+)U"), r"\1") ] # pass one or more include files to the preprocessor, and return a # sequence of text lines containing the #define's that the # preprocessor dumps out. def get_cpp_symbols(*fnames): # write a temporary C file handle, c_file = tempfile.mkstemp(suffix=".c", text=True) for fname in fnames: os.write(handle, "#include <%s>\n" % fname) os.close(handle) try: i, o = os.popen4(r"gccxml.exe --preprocess -dM") i.close() ignores = o.readlines() result = [] log = open("temp.log", "w") print (r"# gccxml.exe %s --preprocess -dM" % c_file) i, o = os.popen4(r"gccxml.exe %s --preprocess -dM" % c_file) i.close() for line in o.readlines(): log.write(line) if not line in ignores: result.append(line) return result finally: os.remove(c_file) ##ignores = [] # ripped from h2py def pytify(body): # replace ignored patterns by spaces for p in ignores: body = p.sub(' ', body) for pat, repl in replaces: body = pat.sub(repl, body) return body def create_pycode(lines, env, stream, include_errors = False): errors = 0 def try_stmt(stmt): try: exec stmt in env except: if include_errors and stream: stream.write("# %s" % stmt) return 1 else: if stream: stream.write(stmt) return 0 for line in lines: match = p_define.match(line) if match: name = match.group(1) if name in env: continue body = line[match.end():] body = pytify(body) stmt = '%s = %s\n' % (name, body.strip()) errors += try_stmt(stmt) continue match = p_macro.match(line) if match: macro, arg = match.group(1, 2) if macro in env: continue body = line[match.end():] body = pytify(body) stmt = 'def %s(%s): return %s\n' % (macro, arg, body) errors += try_stmt(stmt) continue if include_errors and stream: # no pattern matches stream.write("# %s" % line) errors += 1 return errors # script start os.environ["GCCXML_COMPILER"] = "msvc71" lines = get_cpp_symbols("windows.h")#, "winsock.h") ofi = sys.stdout env = {} e = 0 for i in range(10): errors = create_pycode(lines, env, ofi, None) ## print "%d errors in pass %d" % (errors, i) if e == errors: create_pycode(lines, env, sys.stdout, True) print "# processed %d lines into %d definitions" % (len(lines), len(env)) print "# %d errors remaining after %d passes" % (errors, i) break e = errors |
From: Thomas H. <th...@us...> - 2004-09-03 07:31:25
|
Update of /cvsroot/ctypes/ctypes/sandbox/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30697/tools Log Message: Directory /cvsroot/ctypes/ctypes/sandbox/tools added to the repository |
From: Thomas H. <th...@us...> - 2004-09-02 19:59:31
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14503 Modified Files: test_structures.py Log Message: Check for presence of class methods of Structure. Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_structures.py 2 Sep 2004 18:46:22 -0000 1.18 --- test_structures.py 2 Sep 2004 19:59:19 -0000 1.19 *************** *** 243,246 **** --- 243,254 ---- self.failUnlessEqual((cls, msg), (TypeError, "abstract class")) + def test_methods(self): + ## class X(Structure): + ## _fields_ = [] + + self.failUnless("in_dll" in dir(type(Structure))) + self.failUnless("from_address" in dir(type(Structure))) + self.failUnless("in_dll" in dir(type(Structure))) + class PointerMemberTestCase(unittest.TestCase): |
From: Thomas H. <th...@us...> - 2004-09-02 18:46:31
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv972 Modified Files: test_structures.py Log Message: Add test for subclassing Structure without _fields_ (should fail), and without _fields_ but _abstract_ (should succeed). Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** test_structures.py 19 Aug 2004 11:34:52 -0000 1.17 --- test_structures.py 2 Sep 2004 18:46:22 -0000 1.18 *************** *** 228,231 **** --- 228,246 ---- + def test_subclass_creation(self): + meta = type(Structure) + # same as 'class X(Structure): pass' + # fails, since we need either a _fields_ or a _abstract_ attribute + cls, msg = self.get_except(meta, "X", (Structure,), {}) + self.failUnlessEqual((cls, msg), + (AttributeError, "class must define a '_fields_' attribute")) + + def test_abstract_class(self): + class X(Structure): + _abstract_ = "something" + # try 'X()' + cls, msg = self.get_except(eval, "X()", locals()) + self.failUnlessEqual((cls, msg), (TypeError, "abstract class")) + class PointerMemberTestCase(unittest.TestCase): |
From: Thomas H. <th...@us...> - 2004-09-01 12:45:47
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7106 Modified Files: ChangeLog ANNOUNCE Log Message: Record changes. Index: ANNOUNCE =================================================================== RCS file: /cvsroot/ctypes/ctypes/ANNOUNCE,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** ANNOUNCE 27 Aug 2004 17:10:22 -0000 1.10 --- ANNOUNCE 1 Sep 2004 12:45:36 -0000 1.11 *************** *** 28,31 **** --- 28,42 ---- ctypes changes + ctypes now allows calling Python C api functions. The pythonapi + symbol should be used to access these functions, this will + automatically use the correct calling convention and exception + handling. The py_object type is the ctypes variant of 'PyObject *'. + This feature should also work if you are using a static python + build. + + It is now possible to call cdecl functions with more arguments + than the length of the argtypes sequence specifies - this allows + to provide functions like sprintf() with a proper prototype. + It is now possible to create strings or unicode strings if you have the integer address by calling c_char_p(address) or *************** *** 53,62 **** returns the alignment requirements in bytes of a type or instance. - experimental changes - - It is now possible to call Python API functions with ctypes. This - is an experimental feature and will probably change. Please don't - use it yet in production code, and watch the ctypes-users mailing - list. ctypes.com changes --- 64,67 ---- Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** ChangeLog 27 Aug 2004 17:10:22 -0000 1.54 --- ChangeLog 1 Sep 2004 12:45:35 -0000 1.55 *************** *** 1,2 **** --- 1,17 ---- + 2004-09-01 Thomas Heller <th...@py...> + + * (Message): A pythonapi object has been added to the ctypes + package. On windows, it is bound to the python dll, on other + systems it is bound to the current process. + + It allows to access C Python api functions. + + py_object is the ctypes type corresponding to the C 'PyObject *' + type. + + * ctypes: It is now possible to call cdecl functions with more + arguments than the length of the argtypes attribute, even if this + is set. This allows specify argtypes for functions like sprintf(). + 2004-08-27 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-09-01 12:37:49
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5780 Modified Files: test_funcptr.py Log Message: Repair a broken test on linux. Index: test_funcptr.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_funcptr.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** test_funcptr.py 1 Sep 2004 12:12:03 -0000 1.17 --- test_funcptr.py 1 Sep 2004 12:37:38 -0000 1.18 *************** *** 53,61 **** self.failUnlessEqual(s(1, 2), 3) self.failUnlessEqual(c(1, 2), 3) - self.assertRaises(TypeError, s, 1, 2, 3) # The following no longer raises a TypeError - it is now # possible, as in C, to call cdecl functions with more parameters. #self.assertRaises(TypeError, c, 1, 2, 3) self.failUnlessEqual(c(1, 2, 3, 4, 5, 6), 3) def test_structures(self): --- 53,62 ---- self.failUnlessEqual(s(1, 2), 3) self.failUnlessEqual(c(1, 2), 3) # The following no longer raises a TypeError - it is now # possible, as in C, to call cdecl functions with more parameters. #self.assertRaises(TypeError, c, 1, 2, 3) self.failUnlessEqual(c(1, 2, 3, 4, 5, 6), 3) + if not WINFUNCTYPE is CFUNCTYPE: + self.assertRaises(TypeError, s, 1, 2, 3) def test_structures(self): |
From: Thomas H. <th...@us...> - 2004-09-01 12:12:18
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv776 Modified Files: test_funcptr.py Log Message: Allow to call cdecl functions with more arguments than the length of the argtypes attribute, even if this is set. Index: test_funcptr.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_funcptr.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** test_funcptr.py 26 Aug 2004 18:17:56 -0000 1.16 --- test_funcptr.py 1 Sep 2004 12:12:03 -0000 1.17 *************** *** 54,58 **** self.failUnlessEqual(c(1, 2), 3) self.assertRaises(TypeError, s, 1, 2, 3) ! self.assertRaises(TypeError, c, 1, 2, 3) def test_structures(self): --- 54,61 ---- self.failUnlessEqual(c(1, 2), 3) self.assertRaises(TypeError, s, 1, 2, 3) ! # The following no longer raises a TypeError - it is now ! # possible, as in C, to call cdecl functions with more parameters. ! #self.assertRaises(TypeError, c, 1, 2, 3) ! self.failUnlessEqual(c(1, 2, 3, 4, 5, 6), 3) def test_structures(self): |
From: Thomas H. <th...@us...> - 2004-09-01 12:04:09
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31816 Modified Files: callproc.c _ctypes.c Log Message: Allow to call cdecl functions with more arguments than the length of the argtypes attribute, even if this is set. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** callproc.c 26 Aug 2004 19:59:21 -0000 1.100 --- callproc.c 1 Sep 2004 12:03:56 -0000 1.101 *************** *** 818,822 **** PyObject *restype) { ! int i, n, argcount; struct argument result; struct argument *args, *pa; --- 818,822 ---- PyObject *restype) { ! int i, n, argcount, argtype_count; struct argument result; struct argument *args, *pa; *************** *** 832,836 **** args = (struct argument *)alloca(sizeof(struct argument) * argcount); memset(args, 0, sizeof(struct argument) * argcount); ! if (pIunk) { args[0].ffi_type = &ffi_type_pointer; --- 832,836 ---- args = (struct argument *)alloca(sizeof(struct argument) * argcount); memset(args, 0, sizeof(struct argument) * argcount); ! argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; if (pIunk) { args[0].ffi_type = &ffi_type_pointer; *************** *** 848,852 **** arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ ! if (argtypes) { PyObject *v; converter = PyTuple_GET_ITEM(argtypes, i); --- 848,856 ---- arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ ! /* For cdecl functions, we allow more actual arguments ! than the length of the argtypes tuple. ! This is checked in _ctypes::CFuncPtr_Call ! */ ! if (argtypes && argtype_count > i) { PyObject *v; converter = PyTuple_GET_ITEM(argtypes, i); Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.154 retrieving revision 1.155 diff -C2 -d -r1.154 -r1.155 *** _ctypes.c 27 Aug 2004 12:04:14 -0000 1.154 --- _ctypes.c 1 Sep 2004 12:03:57 -0000 1.155 *************** *** 2454,2458 **** required ++; #endif ! if (required != actual) { PyErr_Format(PyExc_TypeError, "this function takes %d argument%s (%d given)", --- 2454,2470 ---- required ++; #endif ! if (dict->flags & FUNCFLAG_CDECL == FUNCFLAG_CDECL) { ! /* For cdecl functions, we allow more actual arguments ! than the length of the argtypes tuple. ! */ ! if (required > actual) { ! PyErr_Format(PyExc_TypeError, ! "this function takes at least %d argument%s (%d given)", ! required, ! required == 1 ? "" : "s", ! actual); ! return NULL; ! } ! } else if (required != actual) { PyErr_Format(PyExc_TypeError, "this function takes %d argument%s (%d given)", |
From: Thomas H. <th...@us...> - 2004-09-01 11:59:18
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30772 Modified Files: test_python_api.py Log Message: Use pythonapi and py_object in the Python api test. Index: test_python_api.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_python_api.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_python_api.py 26 Aug 2004 19:48:50 -0000 1.2 --- test_python_api.py 1 Sep 2004 11:59:02 -0000 1.3 *************** *** 7,19 **** from _ctypes import PyObj_FromPtr - from _ctypes import _SimpleCData - class PyObject(_SimpleCData): - _type_ = "O" - - if sys.platform == "win32": - python = getattr(pydll, "python%s%s" % sys.version_info[:2]) - else: - python = PyDLL(None) - ################################################################ --- 7,10 ---- *************** *** 24,33 **** def test_PyString_FromString(self): ! python.PyString_FromString.restype = PyObject ! python.PyString_FromString.argtypes = (c_char_p,) s = "abc" refcnt = grc(s) ! pyob = python.PyString_FromString(s) self.failUnlessEqual(grc(s), refcnt) self.failUnlessEqual(s, pyob) --- 15,24 ---- def test_PyString_FromString(self): ! pythonapi.PyString_FromString.restype = py_object ! pythonapi.PyString_FromString.argtypes = (c_char_p,) s = "abc" refcnt = grc(s) ! pyob = pythonapi.PyString_FromString(s) self.failUnlessEqual(grc(s), refcnt) self.failUnlessEqual(s, pyob) *************** *** 37,49 **** def test_PyInt_Long(self): ref42 = grc(42) ! python.PyInt_FromLong.restype = PyObject ! self.failUnlessEqual(python.PyInt_FromLong(42), 42) self.failUnlessEqual(grc(42), ref42) ! python.PyInt_AsLong.argtypes = (PyObject,) ! python.PyInt_AsLong.restype = c_int ! res = python.PyInt_AsLong(42) self.failUnlessEqual(grc(res), ref42 + 1) del res --- 28,40 ---- def test_PyInt_Long(self): ref42 = grc(42) ! pythonapi.PyInt_FromLong.restype = py_object ! self.failUnlessEqual(pythonapi.PyInt_FromLong(42), 42) self.failUnlessEqual(grc(42), ref42) ! pythonapi.PyInt_AsLong.argtypes = (py_object,) ! pythonapi.PyInt_AsLong.restype = c_int ! res = pythonapi.PyInt_AsLong(42) self.failUnlessEqual(grc(res), ref42 + 1) del res *************** *** 61,64 **** --- 52,69 ---- self.failUnlessEqual(grc(s), ref) + def test_PyOS_snprintf(self): + PyOS_snprintf = pythonapi.PyOS_snprintf + PyOS_snprintf.argtypes = POINTER(c_char), c_int, c_char_p + + buf = c_buffer(256) + PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes") + self.failUnlessEqual(buf.value, "Hello from ctypes") + + PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes", 1, 2, 3) + self.failUnlessEqual(buf.value, "Hello from ctypes") + + # not enough arguments + self.failUnlessRaises(TypeError, PyOS_snprintf, buf) + if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2004-09-01 11:55:19
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30129 Modified Files: __init__.py Log Message: Don't import os as two times, with different names. A prefabricated pythonapi object which allows to get C Python api functions, using the correct calling convention. A py_object representing Python objects. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** __init__.py 26 Aug 2004 18:14:41 -0000 1.30 --- __init__.py 1 Sep 2004 11:55:05 -0000 1.31 *************** *** 3,11 **** # special developer support to use ctypes from the CVS sandbox, # without installing it ! import os, sys ! _magicfile = os.path.join(os.path.dirname(__file__), ".CTYPES_DEVEL") ! if os.path.isfile(_magicfile): execfile(_magicfile) ! del os, _magicfile __version__ = "0.9.1" --- 3,11 ---- # special developer support to use ctypes from the CVS sandbox, # without installing it ! import os as _os, sys ! _magicfile = _os.path.join(_os.path.dirname(__file__), ".CTYPES_DEVEL") ! if _os.path.isfile(_magicfile): execfile(_magicfile) ! del _magicfile __version__ = "0.9.1" *************** *** 19,24 **** raise Exception, ("Version number mismatch", __version__, _ctypes_version) - import os as _os - if _os.name == "nt": from _ctypes import FormatError --- 19,22 ---- *************** *** 120,123 **** --- 118,124 ---- from _ctypes import _SimpleCData + class py_object(_SimpleCData): + _type_ = "O" + class c_short(_SimpleCData): _type_ = "h" *************** *** 296,299 **** --- 297,305 ---- _restype_ = c_int # default, can be overridden in instances + if _os.name == "nt": + pythonapi = PyDLL("python%s%s" % sys.version_info[:2]) + else: + pythonapi = PyDLL(None) + if _os.name == "nt": |
From: Thomas H. <th...@us...> - 2004-09-01 11:48:11
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28918 Modified Files: .CTYPES_DEVEL Log Message: Import all modules needed. Although this file is executed with execfile(), it should not rely on symbols defined in the executing namespace. Index: .CTYPES_DEVEL =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/.CTYPES_DEVEL,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** .CTYPES_DEVEL 25 Apr 2003 11:44:16 -0000 1.2 --- .CTYPES_DEVEL 1 Sep 2004 11:48:01 -0000 1.3 *************** *** 1,5 **** # -*- python -*- def install(): ! import sys p = os.path.abspath( --- 1,5 ---- # -*- python -*- def install(): ! import sys, os p = os.path.abspath( |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:31:24
|
Update of /cvsroot/ctypes/ctypes-java/src/jni/Debug In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19798/src/jni/Debug Modified Files: ctypes4j.dll Log Message: Index: ctypes4j.dll =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/Debug/ctypes4j.dll,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 Binary files /tmp/cvs98Hvlr and /tmp/cvsOnHqdH differ |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:30:22
|
Update of /cvsroot/ctypes/ctypes-java/src/jni In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19625/src/jni Modified Files: support.c ctypes_java_CCallbackFunction.h ctypesj.dsp module.c CCallbackFunction.c support.h CFunction.c Added Files: ctypesj.ncb ctypesj.plg ctypesj.opt Log Message: --- NEW FILE: ctypesj.ncb --- (This appears to be a binary file; contents omitted.) Index: support.c =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/support.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** support.c 21 Mar 2004 23:43:35 -0000 1.3 --- support.c 29 Aug 2004 01:30:03 -0000 1.4 *************** *** 193,197 **** } ! void SetException(JNIEnv * env, DWORD code) { char *lpMsgBuf; --- 193,205 ---- } ! DWORD HandleException(EXCEPTION_POINTERS *ptrs, ! DWORD *pdw, EXCEPTION_RECORD *record) ! { ! *pdw = ptrs->ExceptionRecord->ExceptionCode; ! *record = *ptrs->ExceptionRecord; ! return EXCEPTION_EXECUTE_HANDLER; ! } ! ! void SetException(JNIEnv * env, DWORD code, EXCEPTION_RECORD *pr) { char *lpMsgBuf; --- NEW FILE: ctypesj.opt --- (This appears to be a binary file; contents omitted.) Index: CFunction.c =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/CFunction.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** CFunction.c 23 Mar 2004 06:37:34 -0000 1.6 --- CFunction.c 29 Aug 2004 01:30:03 -0000 1.7 *************** *** 42,46 **** #else #include <dlfcn.h> - #include <ffi.h> #include <malloc.h> #include <alloca.h> --- 42,45 ---- *************** *** 48,51 **** --- 47,51 ---- #endif + #include <ffi.h> #include <jni.h> #include "ctypes_java_CFunction.h" *************** *** 124,127 **** --- 124,129 ---- } + + static jobject GetResult(JNIEnv * env, jclass restype, JavaCArgObject *result) { *************** *** 147,150 **** --- 149,159 ---- } break; + case 'h': + if ((*env)->IsAssignableFrom(env, restype, Class_CShort)) { + mid = (*env)->GetMethodID(env, restype, "<init>", "(S)V"); + ret = (*env)->NewObject(env, restype, mid, result->value.h); + return ret; + } + break; case 'i': case 'I': *************** *** 244,248 **** if ((*env)->IsInstanceOf(env, obj, Class_CCallbackFunction)) { ! jfieldID fid = (*env)->GetFieldID(env, Class_CCallbackFunction, "address", "J"); jbyte * buf = (jbyte*) (*env)->GetLongField(env, obj, fid); parm->tag = 'p'; --- 253,257 ---- if ((*env)->IsInstanceOf(env, obj, Class_CCallbackFunction)) { ! jfieldID fid = (*env)->GetFieldID(env, Class_CCallbackFunction, "thunk", "J"); jbyte * buf = (jbyte*) (*env)->GetLongField(env, obj, fid); parm->tag = 'p'; *************** *** 515,541 **** - #ifndef MS_WIN32 - /* - There's a problem with current CVS versions of libffi (2003-01-21). - It redefines ffi_type_slong and ffi_type_ulong to - ffi_type_sint64 and ffi_type_uint64. - - Fortunately, ctypes' unittests catch this. - - printf("SIZEOF_LONG %d\n", SIZEOF_LONG); - printf("ffi_type_slong %p\n", &ffi_type_slong); - printf("ffi_type_sint64 %p\n", &ffi_type_sint64); - printf("ffi_type_sint %p\n", &ffi_type_sint); - printf("ffi_type_sint32 %p\n", &ffi_type_sint32); - */ - #if (SIZEOF_LONG_LONG == 8 && SIZEOF_LONG == 4) - #undef ffi_type_ulong - #define ffi_type_ulong ffi_type_uint32 - #define ffi_type_ulonglong ffi_type_uint64 - #undef ffi_type_slong - #define ffi_type_slong ffi_type_sint32 - #define ffi_type_slonglong ffi_type_sint64 - #endif ffi_type *tag2ffitype(char tag) --- 524,528 ---- *************** *** 560,567 **** --- 547,557 ---- case 'L': return &ffi_type_ulong; + #ifndef MS_WIN32 case 'q': return &ffi_type_slonglong; + case 'Q': return &ffi_type_ulonglong; + #endif case 'z': case 'Z': *************** *** 600,603 **** --- 590,594 ---- int argcount) { + char buffer[200]; ffi_cif cif; ffi_type *rtype; *************** *** 605,608 **** --- 596,605 ---- void **values; int i; + int cc; + #ifdef MS_WIN32 + int delta; + DWORD dwExceptionCode; + EXCEPTION_RECORD record; + #endif atypes = (ffi_type **)alloca(argcount * sizeof(ffi_type *)); *************** *** 614,619 **** } rtype = tag2ffitype(res->tag); ! ! if (FFI_OK != ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argcount, rtype, --- 611,622 ---- } rtype = tag2ffitype(res->tag); ! ! cc = FFI_DEFAULT_ABI; ! #ifdef MS_WIN32 ! if ((flags & FUNCFLAG_CDECL) == 0) ! cc = FFI_STDCALL; ! dwExceptionCode = 0; ! #endif ! if (FFI_OK != ffi_prep_cif(&cif, cc, argcount, rtype, *************** *** 623,836 **** } ! ffi_call(&cif, (void *)pProc, &res->value, values); ! return 0; ! } ! ! #else ! ! #pragma optimize ("", off) ! /* ! * Can you figure out what this does? ;-) ! */ ! static void __stdcall push(void) ! { ! } ! ! static int _call_function_pointer(JNIEnv * env, int flags, ! PPROC pProc, ! JavaCArgObject **parms, ! JavaCArgObject *res, ! int argcount) ! { ! char buffer[200]; ! int i; ! DWORD dwExceptionCode; ! int new_esp, save_esp; ! int argbytes = 0; ! ! /* ! The idea was to do this in C, without assembler. But how can we ! guard against passing the wrong number of arguments? How do we ! save and restore the stack pointer? ! ! Apparently MSVC does not use ESP addressing but EBP addressing, ! so we can use local variables (on the stack) for saving and ! restoring the value of ESP! ! */ ! ! _asm mov save_esp, esp; ! new_esp = save_esp; ! ! #pragma warning (disable: 4087) ! /* Both __stdcall and __cdecl calling conventions pass the arguments ! 'right to left'. The difference is in the stack cleaning: __stdcall ! __stdcall functions pop their arguments off the stack themselves, ! __cdecl functions leave this to the caller. ! */ ! for (i = argcount-1; i >= 0; --i) { ! float f; ! ! switch(parms[i]->tag) { ! case 'c': ! push(parms[i]->value.c); ! argbytes += sizeof(int); ! break; ! ! /* This works, although it doesn't look correct! */ ! case 'b': ! case 'h': ! case 'i': ! case 'B': ! case 'H': ! case 'I': ! case 'u': ! push(parms[i]->value.i); ! argbytes += sizeof(int); ! break; ! case 'l': ! case 'L': ! push(parms[i]->value.l); ! argbytes += sizeof(long); ! break; ! #ifdef HAVE_LONG_LONG ! case 'q': ! case 'Q': ! push(parms[i]->value.q); ! argbytes += sizeof(PY_LONG_LONG); ! break; ! #endif ! case 'f': ! case 'F': ! /* Cannot use push(parms[i]->value.f) here, because ! the C compiler would promote it to a double ! */ ! f = parms[i]->value.f; ! _asm push f; ! argbytes += sizeof(float); ! break; ! case 'd': ! push(parms[i]->value.d); ! argbytes += sizeof(double); ! break; ! case 'z': ! case 'Z': ! case 'p': ! case 'P': ! case 'X': /* BSTR */ ! push(parms[i]->value.p); ! argbytes += sizeof(void *); ! break; ! default: ! /* ! PyErr_Format(PyExc_ValueError, ! "BUG: Invalid format tag '%c' for argument", ! parms[i]->tag); ! /* try to clean the stack */ ! _asm mov esp, save_esp; ! return -1; ! } ! } ! ! #pragma warning (default: 4087) ! ! dwExceptionCode = 0; #ifndef DEBUG_EXCEPTIONS __try { #endif ! switch(res->tag) { ! case 'c': ! res->value.c = ((char(*)())pProc)(); ! break; ! case 'B': ! case 'b': ! res->value.b = ((char(*)())pProc)(); ! break; ! case 'H': ! case 'h': ! res->value.h = ((short(*)())pProc)(); ! break; ! case 'I': ! case 'i': ! res->value.i = ((int(*)())pProc)(); ! break; ! case 'l': ! case 'L': ! res->value.l = ((long(*)())pProc)(); ! break; ! case 'd': ! res->value.d = ((double(*)())pProc)(); ! break; ! case 'f': ! case 'F': ! res->value.f = ((float(*)())pProc)(); ! break; ! #ifdef HAVE_LONG_LONG ! case 'q': ! case 'Q': ! res->value.q = ((PY_LONG_LONG(*)())pProc)(); ! break; ! #endif ! case 'z': ! case 'Z': ! case 'p': ! case 'P': ! res->value.p = ((void *(*)())pProc)(); ! break; ! case 'v': ! (pProc)(); ! break; ! default: ! /* XXX Signal bug */ ! res->tag |= 0x80; ! break; ! } } ! __except (dwExceptionCode = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER) { ; } ! ! _asm sub new_esp, esp; ! _asm mov esp, save_esp; ! ! if (dwExceptionCode) { ! SetException(env, dwExceptionCode); ! return -1; ! } ! ! if (res->tag & 0x80) { ! sprintf(buffer, "BUG: Invalid format tag for restype '%c'", res->tag & ~0x80); ! JNU_ThrowByName(env, "ctypes/java/CException", buffer); return -1; } ! ! ! if (flags & FUNCFLAG_CDECL) /* Clean up stack if needed */ ! new_esp -= argbytes; ! if (new_esp < 0) { if (flags & FUNCFLAG_CDECL) { ! sprintf(buffer, "Procedure called with not enough" "arguments (%d bytes missing) " ! "or wrong calling convention", -new_esp); JNU_ThrowByName(env, "ctypes/java/CException", buffer); } else { sprintf(buffer, "Procedure probably called with not enough " ! "arguments (%d bytes missing)", -new_esp); JNU_ThrowByName(env, "ctypes/java/CException", buffer); } return -1; ! ! } ! if (new_esp > 0) { sprintf(buffer, "Procedure probably called with too many " ! "arguments (%d bytes in excess)", new_esp); JNU_ThrowByName(env, "ctypes/java/CException", buffer); - return -1; - } - return 0; - } - #pragma optimize ("", on) #endif --- 626,670 ---- } ! #ifdef MS_WIN32 #ifndef DEBUG_EXCEPTIONS __try { #endif ! delta = ! #endif ! ffi_call(&cif, (void *)pProc, &res->value, values); ! #ifdef MS_WIN32 ! #ifndef DEBUG_EXCEPTIONS } ! __except (HandleException(GetExceptionInformation(), ! &dwExceptionCode, &record)) { ; } ! #endif ! #endif ! #ifdef MS_WIN32 if (dwExceptionCode) { ! SetException(env, dwExceptionCode, &record); return -1; } ! if (delta < 0) { if (flags & FUNCFLAG_CDECL) { ! sprintf(buffer, "Procedure called with not enough" "arguments (%d bytes missing) " ! "or wrong calling convention", -delta); JNU_ThrowByName(env, "ctypes/java/CException", buffer); } else { sprintf(buffer, "Procedure probably called with not enough " ! "arguments (%d bytes missing)", -delta); JNU_ThrowByName(env, "ctypes/java/CException", buffer); } return -1; ! } else if (delta > 0) { sprintf(buffer, "Procedure probably called with too many " ! "arguments (%d bytes in excess)", delta); JNU_ThrowByName(env, "ctypes/java/CException", buffer); return -1; } #endif + return 0; + } Index: CCallbackFunction.c =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/CCallbackFunction.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CCallbackFunction.c 19 Apr 2004 13:39:04 -0000 1.5 --- CCallbackFunction.c 29 Aug 2004 01:30:03 -0000 1.6 *************** *** 27,31 **** #include <memory.h> #else - #include <ffi.h> #include <alloca.h> #include <string.h> --- 27,30 ---- *************** *** 35,39 **** #endif ! #include <jni.h> #include <malloc.h> --- 34,38 ---- #endif ! #include <ffi.h> #include <jni.h> #include <malloc.h> *************** *** 47,58 **** */ - #ifdef MS_WIN32 - typedef struct { - BYTE *pStart; - BYTE *pEnd; - } CALLBACKINFO; - static CALLBACKINFO ti; - #endif THUNK AllocFunctionCallback(jobject callable, --- 46,50 ---- *************** *** 63,78 **** - #ifdef MS_WIN32 - THUNK AllocCallback(jobject callable, - int nArgBytes, - jobject converters, - DWORD RouterAddress, - int is_cdecl); - - #endif - - - - static void __stdcall CallJavaObject(void *mem, char *format, --- 55,58 ---- *************** *** 81,85 **** void **pArgs); ! JNIEXPORT jlong JNICALL Java_ctypes_java_CCallbackFunction_init (JNIEnv * env, jobject obj, jclass restype, jobjectArray converters, jint numbytes, jint calltype) { --- 61,92 ---- void **pArgs); ! ! typedef struct { ! ffi_closure cl; /* the C callable */ ! ffi_cif cif; ! jobjectArray converters; ! jobject callable; ! char *format; ! ffi_type *atypes[0]; ! } ffi_info; ! ! ! JNIEXPORT void JNICALL Java_ctypes_java_CCallbackFunction_pokeThunk(JNIEnv * env, jobject obj, jlong val) { ! long peer = (long) (*env)->GetLongField(env, obj, FID_CType_address); ! jlong * i = (jint*) peer; ! *i = val; ! } ! ! /* ! * Class: NativeInt ! * Method: getInt ! * Signature: ()I ! */ ! JNIEXPORT jlong JNICALL Java_ctypes_java_CCallbackFunction_peekThunk(JNIEnv * env, jobject obj) { ! long peer = (long) (*env)->GetLongField(env, obj, FID_CType_address); ! jlong * i = (jint*) peer; ! return *i; ! } ! JNIEXPORT jlong JNICALL Java_ctypes_java_CCallbackFunction_init (JNIEnv * env, jobject obj, jclass restype, jobjectArray converters, jint numbytes, jint calltype) { *************** *** 99,102 **** --- 106,123 ---- } + JNIEXPORT void JNICALL Java_ctypes_java_CCallbackFunction_fini + (JNIEnv * env, jobject obj, jlong address) { + jobject callable; + jobjectArray converters; + int tmp = (int) address; + ffi_info * thunk = (ffi_info *) tmp; + + callable = thunk->callable; + converters = thunk->converters, + + (*env)->DeleteGlobalRef(env, callable); + (*env)->DeleteGlobalRef(env, converters); + free(thunk); + } /* * based on the type of the object and the format, extract the value of the jobject into the result *************** *** 127,154 **** } - #ifdef MS_WIN32 - /* - finalize the trampoline. In this case this involves deleting the - global references stored in the trampoline. - */ - JNIEXPORT void JNICALL Java_ctypes_java_CCallbackFunction_fini - (JNIEnv * env, jobject obj, jlong address) { - BYTE *pCallback, *pConverters, *pCalladdr; - jobject callable; - jobjectArray arguments; - long trampoline; - trampoline = (long) address; - pCallback = (BYTE*) trampoline; - pConverters = pCallback + (ti.pEnd - ti.pStart) - 12; - pCalladdr = pCallback + (ti.pEnd - ti.pStart) - 8; - callable = (jobject) *(DWORD *)pConverters; - arguments = (jobject) *(DWORD *)pCalladdr; - - (*env)->DeleteGlobalRef(env, callable); - (*env)->DeleteGlobalRef(env, arguments); - free((void *)trampoline); - } - #endif /* --- 148,152 ---- *************** *** 201,206 **** #ifdef MS_WIN32 ! DWORD dwExceptionCode = 0; #endif JNIEnv* env = JNU_GetEnv(); --- 199,207 ---- #ifdef MS_WIN32 ! int delta; ! DWORD dwExceptionCode; ! EXCEPTION_RECORD record; #endif + JNIEnv* env = JNU_GetEnv(); *************** *** 274,279 **** } ! __except (dwExceptionCode = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER) { ! SetException(env, dwExceptionCode); return; } --- 275,281 ---- } ! __except (HandleException(GetExceptionInformation(), ! &dwExceptionCode, &record)) { ! SetException(env, dwExceptionCode, NULL); return; } *************** *** 287,559 **** - #ifdef MS_WIN32 - static int __stdcall i_CallJavaObject(jobject callable, - jobject converters, - void **pArgs) - { - JavaCArgObject result; - CallJavaObject(&result.value, "i", callable, converters, pArgs); - return result.value.i; - } - static double __stdcall d_CallJavaObject(jobject callable, - jobject converters, - void **pArgs) - { - JavaCArgObject result; - CallJavaObject(&result.value, "d", callable, converters, pArgs); - return result.value.d; - } - static float __stdcall f_CallJavaObject(jobject callable, - jobject converters, - void **pArgs) - { - JavaCArgObject result; - CallJavaObject(&result.value, "f", callable, converters, pArgs); - return result.value.f; - } - - #ifdef HAVE_LONG_LONG - static PY_LONG_LONG __stdcall q_CallJavaObject(jobject callable, - jobject converters, - void **pArgs) - { - JavaCArgObject result; - CallJavaObject(&result.value, "L", callable, converters, pArgs); - return result.value.q; - } - #endif - - #define NOSTACKFRAME - //#define BREAKPOINTS - - #pragma warning( disable : 4035 ) /* Disable warning about no return value */ - /* - * Callbacks are small blocks of code which create an interface between code - * using different calling conventions. - * In this case, an interface from __stdcall and __cdecl C-functions to python - * callable objects is provided. - * - * Callbacks are created by allocating some memory, copying the bytes from this - * template into it, and configuring the callback by setting the number of - * argument bytes and the address of the python object. - * For copying and configuring the callback we need the addresses of some - * assembler labels. These addresses are returned when the CallbackTemplate - * is called directly, without beeing configured. - */ - static int __declspec ( naked ) CallbackTemplate(DWORD arg) - { - /* This function will be called with the __stdcall calling convention: - * Arguments are pushed in right to left order onto the stack. - * Callee has to remove its own arguments from stack. - */ - _asm { - CallbackStart: - #ifdef BREAKPOINTS - int 3 - #endif - #ifndef NOSTACKFRAME - push ebp - mov ebp, esp - #endif - /* Trick for position independent code, transferring NumberArgs into ecx */ - call _1 - _1: - pop eax - add eax, OFFSET NumberArgs - sub eax, OFFSET _1 - mov ecx, [eax] - - /* Trick for position independent code, transferring CallAddress into edx */ - call _2 - _2: - pop eax - add eax, OFFSET CallAddress - sub eax, OFFSET _2 - mov edx, [eax] - - or edx, edx - jz ReturnInfo - - call _2a - _2a: - pop eax - add eax, OFFSET ConvertersAddress - sub eax, OFFSET _2a - mov ecx, [eax] - - #ifdef NOSTACKFRAME - mov eax, esp - add eax, 4 // return address is on stack - #else - mov eax, ebp - add eax, 8 // return address and ebp is on stack - #endif - /* push arguments in reverse order - * Register contents: - * EAX: Pointer to arguments - * ECX: Pointer to converters - * EDX: Pointer to python callable object - */ - push eax - push ecx - push edx - - /* Trick for position independent code, transferring CallAddress into eax */ - call _3 - _3: - pop eax - add eax, OFFSET RouterAddress - sub eax, OFFSET _3 - - call[eax] - - #ifndef NOSTACKFRAME - mov esp, ebp - pop ebp - #endif - #ifdef BREAKPOINTS - int 3 - #endif - /* For __stdcall functions: */ - _emit 0xC2 /* ret ... */ - /* __cdecl functions would require a simple 'ret' 0xC3 here... */ - /* - * Static storage for four DWORDS, containing the callbacks number of arguments - * and the address of the python object to call - * Note that NumberArgs must follow immediately the 'ret' instruction - * above! - */ - NumberArgs: - _emit 0 - _emit 0 - _emit 0 - _emit 0 - ConvertersAddress: - _emit 0 - _emit 0 - _emit 0 - _emit 0 - CallAddress: /* Python object to call */ - _emit 0 - _emit 0 - _emit 0 - _emit 0 - RouterAddress: /* C-function to route call */ - _emit 0 - _emit 0 - _emit 0 - _emit 0 - CallbackEnd: - - ReturnInfo: - mov eax, OFFSET CallbackStart - mov edx, OFFSET CallbackEnd - - #ifndef NOSTACKFRAME - mov esp, ebp - pop ebp - #endif - ret 4 - } - } - #pragma warning( default : 4035 ) /* Reenable warning about no return value */ - - /*****************************************************************************/ - - - - /* - * Allocate a callback and configure it - */ - static THUNK AllocCallback(jobject callable, int nArgBytes, - jobjectArray converters, DWORD RouterAddress, - int is_cdecl) - { - BYTE *pCallback, *pNargBytes, *pConverters, *pCalladdr, *pRouter; - - pCallback = malloc(ti.pEnd - ti.pStart); - memcpy(pCallback, ti.pStart, ti.pEnd - ti.pStart); - pNargBytes = pCallback +(ti.pEnd - ti.pStart) - 16; - pConverters = pCallback + (ti.pEnd - ti.pStart) - 12; - pCalladdr = pCallback + (ti.pEnd - ti.pStart) - 8; - pRouter = pCallback + (ti.pEnd - ti.pStart) - 4; - *(DWORD *)pNargBytes = nArgBytes; - if (is_cdecl) - ((BYTE *)pNargBytes)[-1] = 0xC3; /* ret: for cdecl */ - else - ((BYTE *)pNargBytes)[-1] = 0xC2; /* ret <args>: for stdcall */ - *(DWORD *)pConverters = (DWORD)converters; - *(DWORD *)pCalladdr = (DWORD)callable; - *(DWORD *)pRouter = RouterAddress; - return (THUNK)pCallback; - } - - - THUNK AllocFunctionCallback(jobject callable, - int nArgBytes, - jobjectArray converters, - jclass restype, - int is_cdecl) - { - JavaCArgObject result; - DWORD func; - jclass newExcCls; - char buf[200]; - JNIEnv* env = JNU_GetEnv(); - - PrepareResult(env, restype, &result); - switch (result.tag) { - /* "bBhHiIlLqQdfP" */ - case 'b': - case 'B': - case 'h': - case 'H': - case 'i': - case 'I': - case 'l': - case 'L': - case 'P': - /* Everything is an integer, only float, double, LONG_LONG is different */ - func = (DWORD)i_CallJavaObject; - break; - #ifdef HAVE_LONG_LONG - case 'q': - case 'Q': - func = (DWORD)q_CallJavaObject; - break; - #endif - case 'd': - func = (DWORD)d_CallJavaObject; - break; - case 'f': - case 'F': - func = (DWORD)f_CallJavaObject; - break; - default: - sprintf(buf, "invalid restype %c", result.tag); - newExcCls = (*env)->FindClass(env, "ctypes/java/CException"); - (*env)->ThrowNew(env, newExcCls, buf); - return NULL; - } - /* XXX restype -> CallJavaObject */ - return AllocCallback(callable, - nArgBytes, - converters, - func, - is_cdecl); - } - - #else /* ! MS_WIN32 */ - - typedef struct { - ffi_closure cl; /* the C callable */ - ffi_cif cif; - jobjectArray converters; - jobject callable; - char *format; - ffi_type *atypes[0]; - } ffi_info; static void closure_fcn(ffi_cif *cif, --- 289,294 ---- *************** *** 562,565 **** --- 297,302 ---- void *userdata) { + int i; + void **pArgs; ffi_info * p = userdata; JNIEnv* env = JNU_GetEnv(); *************** *** 569,579 **** } ! void **pArgs = alloca(sizeof(void *) * nArgs); ! int i; /* args is an array containing pointers to pointers to arguments, but CallJavaObject expects an array containing pointers to arguments. */ ! for (i = 0; i < nArgs; ++i) { pArgs[i] = *(void ***)args[i]; } --- 306,316 ---- } ! pArgs = alloca(sizeof(void *) * nArgs); ! /* args is an array containing pointers to pointers to arguments, but CallJavaObject expects an array containing pointers to arguments. */ ! for ( i = 0; i < nArgs; ++i) { pArgs[i] = *(void ***)args[i]; } *************** *** 648,652 **** break; case 'v': ! p->format = 'v'; break; default: --- 385,389 ---- break; case 'v': ! p->format = "v"; break; default: *************** *** 662,680 **** return (THUNK)p; } - #endif - void FreeCallback(THUNK thunk) - { - free(thunk); - } - void init_callbacks_in_module() - { - #ifdef MS_WIN32 - CALLBACKINFO (__stdcall *pFunc)(DWORD); - pFunc = (CALLBACKINFO (__stdcall *)(DWORD)) CallbackTemplate; - ti = pFunc(0); - #endif ! } --- 399,405 ---- return (THUNK)p; } ! Index: module.c =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/module.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** module.c 21 Mar 2004 23:43:35 -0000 1.4 --- module.c 29 Aug 2004 01:30:03 -0000 1.5 *************** *** 208,213 **** return JNI_ERR; } - /* init the callbacks */ - init_callbacks_in_module(); return JNI_VERSION_1_2; --- 208,211 ---- Index: support.h =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/support.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** support.h 21 Mar 2004 23:43:35 -0000 1.4 --- support.h 29 Aug 2004 01:30:03 -0000 1.5 *************** *** 22,26 **** #ifdef MS_WIN32 ! void SetException(JNIEnv * env, DWORD code); #endif --- 22,27 ---- #ifdef MS_WIN32 ! DWORD HandleException(EXCEPTION_POINTERS *ptrs, DWORD *pdw, EXCEPTION_RECORD *record); ! void SetException(JNIEnv * env, DWORD code, EXCEPTION_RECORD *pr); #endif Index: ctypes_java_CCallbackFunction.h =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/ctypes_java_CCallbackFunction.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ctypes_java_CCallbackFunction.h 21 Mar 2004 23:43:35 -0000 1.3 --- ctypes_java_CCallbackFunction.h 29 Aug 2004 01:30:03 -0000 1.4 *************** *** 1,32 **** /* DO NOT EDIT THIS FILE - it is machine generated */ ! #include <jni.h> /* Header for class ctypes_java_CCallbackFunction */ #ifndef _Included_ctypes_java_CCallbackFunction ! #define _Included_ctypes_java_CCallbackFunction #ifdef __cplusplus extern "C" { ! #endif ! /* Inaccessible static: SYNCDIR_TOC */ ! /* Inaccessible static: SYNCDIR_TOJAVA */ ! /* Inaccessible static: class_00024ctypes_00024java_00024CInt */ ! /* ! * Class: ctypes_java_CCallbackFunction ! * Method: init ! * Signature: (Ljava/lang/Class;[Ljava/lang/Class;II)J ! */ ! JNIEXPORT jlong JNICALL Java_ctypes_java_CCallbackFunction_init (JNIEnv *, jobject, jclass, jobjectArray, jint, jint); ! ! /* ! * Class: ctypes_java_CCallbackFunction ! * Method: fini ! * Signature: (J)V ! */ ! JNIEXPORT void JNICALL Java_ctypes_java_CCallbackFunction_fini (JNIEnv *, jobject, jlong); ! #ifdef __cplusplus } ! #endif ! #endif --- 1,48 ---- /* DO NOT EDIT THIS FILE - it is machine generated */ ! #include <jni.h> /* Header for class ctypes_java_CCallbackFunction */ #ifndef _Included_ctypes_java_CCallbackFunction ! #define _Included_ctypes_java_CCallbackFunction #ifdef __cplusplus extern "C" { ! #endif ! /* Inaccessible static: SYNCDIR_TOC */ ! /* Inaccessible static: SYNCDIR_TOJAVA */ ! /* Inaccessible static: class_00024ctypes_00024java_00024CInt */ ! /* ! * Class: ctypes_java_CCallbackFunction ! * Method: init ! * Signature: (Ljava/lang/Class;[Ljava/lang/Class;II)J ! */ ! JNIEXPORT jlong JNICALL Java_ctypes_java_CCallbackFunction_init (JNIEnv *, jobject, jclass, jobjectArray, jint, jint); ! ! /* ! * Class: ctypes_java_CCallbackFunction ! * Method: fini ! * Signature: (J)V ! */ ! JNIEXPORT void JNICALL Java_ctypes_java_CCallbackFunction_fini (JNIEnv *, jobject, jlong); ! ! /* ! * Class: ctypes_java_CCallbackFunction ! * Method: pokeThunk ! * Signature: (J)V ! */ ! JNIEXPORT void JNICALL Java_ctypes_java_CCallbackFunction_pokeThunk ! (JNIEnv *, jobject, jlong); ! ! /* ! * Class: ctypes_java_CCallbackFunction ! * Method: peekThunk ! * Signature: ()J ! */ ! JNIEXPORT jlong JNICALL Java_ctypes_java_CCallbackFunction_peekThunk ! (JNIEnv *, jobject); ! #ifdef __cplusplus } ! #endif ! #endif Index: ctypesj.dsp =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/jni/ctypesj.dsp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ctypesj.dsp 11 Mar 2004 01:35:35 -0000 1.2 --- ctypesj.dsp 29 Aug 2004 01:30:03 -0000 1.3 *************** *** 44,48 **** # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /YX /FD /c ! # ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\j2sdk1.4.2_03\include" /I "C:\j2sdk1.4.2_03\include\win32" /D "MS_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 --- 44,48 ---- # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /YX /FD /c ! # ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\j2sdk1.4.2_03\include" /I "C:\j2sdk1.4.2_03\include\win32" /I "E:\eclipse\workspace\ctypes-java\src\jni\libffi_msvc" /D "MS_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 *************** *** 54,58 **** LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 !ELSEIF "$(CFG)" == "ctypesj - Win32 Debug" --- 54,58 ---- LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/ctypes4j.dll" !ELSEIF "$(CFG)" == "ctypesj - Win32 Debug" *************** *** 70,74 **** # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /YX /FD /GZ /c ! # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\j2sdk1.4.2_03\include" /I "C:\j2sdk1.4.2_03\include\win32" /D "MS_WIN32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 --- 70,74 ---- # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /YX /FD /GZ /c ! # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\j2sdk1.4.2_03\include" /I "C:\j2sdk1.4.2_03\include\win32" /I "E:\eclipse\workspace\ctypes-java\src\jni\libffi_msvc" /D "MS_WIN32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 *************** *** 80,84 **** LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept !ENDIF --- 80,84 ---- LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/ctypes4j.dll" /pdbtype:sept !ENDIF *************** *** 129,133 **** # Begin Source File ! SOURCE=.\CMalloc.cpp # End Source File # Begin Source File --- 129,133 ---- # Begin Source File ! SOURCE=.\CMalloc.c # End Source File # Begin Source File *************** *** 149,158 **** --- 149,174 ---- # Begin Source File + SOURCE=.\libffi_msvc\ffi.c + # End Source File + # Begin Source File + SOURCE=.\module.c # End Source File # Begin Source File + SOURCE=.\libffi_msvc\prep_cif.c + # End Source File + # Begin Source File + SOURCE=.\support.c # End Source File + # Begin Source File + + SOURCE=.\libffi_msvc\types.c + # End Source File + # Begin Source File + + SOURCE=.\libffi_msvc\win32.c + # End Source File # End Group # Begin Group "Header Files" *************** *** 217,220 **** --- 233,256 ---- # Begin Source File + SOURCE=.\ctypes_java_WinDLL.h + # End Source File + # Begin Source File + + SOURCE=.\libffi_msvc\ffi.h + # End Source File + # Begin Source File + + SOURCE=.\libffi_msvc\ffi_common.h + # End Source File + # Begin Source File + + SOURCE=.\libffi_msvc\fficonfig.h + # End Source File + # Begin Source File + + SOURCE=.\libffi_msvc\ffitarget.h + # End Source File + # Begin Source File + SOURCE=.\javactypes.h # End Source File --- NEW FILE: ctypesj.plg --- <html> <body> <pre> <h1>Build Log</h1> <h3> --------------------Configuration: ctypesj - Win32 Debug-------------------- </h3> <h3>Command Lines</h3> Creating temporary file "C:\DOCUME~1\bradley\LOCALS~1\Temp\RSP1C7.tmp" with contents [ /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\j2sdk1.4.2_03\include" /I "C:\j2sdk1.4.2_03\include\win32" /I "E:\eclipse\workspace\ctypes-java\src\jni\libffi_msvc" /D "MS_WIN32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTYPESJ_EXPORTS" /Fo"Debug/" /Fd"Debug/" /FD /c "E:\eclipse\workspace\ctypes-java\src\jni\CFunction.c" ] Creating command line "cl.exe @C:\DOCUME~1\bradley\LOCALS~1\Temp\RSP1C7.tmp" Creating temporary file "C:\DOCUME~1\bradley\LOCALS~1\Temp\RSP1C8.tmp" with contents [ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"Debug/ctypes4j.pdb" /debug /machine:I386 /out:"Debug/ctypes4j.dll" /implib:"Debug/ctypes4j.lib" /pdbtype:sept ".\Debug\CBuffer.obj" ".\Debug\CByte.obj" ".\Debug\CCallbackFunction.obj" ".\Debug\CDLL.obj" ".\Debug\CDouble.obj" ".\Debug\CFloat.obj" ".\Debug\CFunction.obj" ".\Debug\CInt.obj" ".\Debug\CLongLong.obj" ".\Debug\CMalloc.obj" ".\Debug\CPointer.obj" ".\Debug\CShort.obj" ".\Debug\CUlong.obj" ".\Debug\CWChar.obj" ".\Debug\ffi.obj" ".\Debug\module.obj" ".\Debug\prep_cif.obj" ".\Debug\support.obj" ".\Debug\types.obj" ".\Debug\win32.obj" ] Creating command line "link.exe @C:\DOCUME~1\bradley\LOCALS~1\Temp\RSP1C8.tmp" <h3>Output Window</h3> Compiling... CFunction.c e:\eclipse\workspace\ctypes-java\src\jni\cfunction.c(275) : warning C4244: '=' : conversion from '__int64 ' to 'long ', possible loss of data Linking... <h3>Results</h3> ctypes4j.dll - 0 error(s), 1 warning(s) </pre> </body> </html> |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:28:35
|
Update of /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/win32/sspi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19501/src/java/ctypes/java/win32/sspi Added Files: TimeStamp.java PSecBufferDesc.java SecurityInteger.java CredHandle.java PTimeStamp.java PSecBuffer.java CtxtHandle.java PCtxtHandle.java SecPkgInfoA.java SecBuffer.java SecBufferDesc.java SSPI.java PCredHandle.java PSecPkgInfoA.java SecHandle.java Log Message: --- NEW FILE: PTimeStamp.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CPointer; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class PTimeStamp extends CPointer { public SecurityInteger stamp = new SecurityInteger(); public PTimeStamp() throws Exception { super(); setSubject(stamp); } } --- NEW FILE: SecBuffer.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; import ctypes.java.CPointer; import ctypes.java.CStruct; import ctypes.java.CType; import ctypes.java.CULong; /** typedef struct _SecBuffer { unsigned long cbBuffer; // Size of the buffer, in bytes unsigned long BufferType; // Type of the buffer (below) void SEC_FAR * pvBuffer; // Pointer to the buffer } SecBuffer, SEC_FAR * PSecBuffer; */ public class SecBuffer extends CStruct { public CULong cbBuffer = new CULong(); public CULong BufferType = new CULong(); public CPointer pvBuffer = new CPointer(); public SecBuffer() throws CException { super(); CType[] e = { cbBuffer, BufferType, pvBuffer }; setElements(e); } } --- NEW FILE: PSecPkgInfoA.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; import ctypes.java.CPointer; import ctypes.java.CType; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class PSecPkgInfoA extends CPointer { public PSecPkgInfoA() throws CException { super(); } public CType getSubject() throws CException { if (subject == null) { subject = new SecPkgInfoA(); subject.setAddress(getValue(), CType.SYNCDIR_TOJAVA); } else { if (isMemoryBacked()) { long v = getAddress(); long j = subject.getAddress(); if (v != j) { subject.setAddress(v, CType.SYNCDIR_TOJAVA); } } } return subject; } } --- NEW FILE: SecurityInteger.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; import ctypes.java.CLong; import ctypes.java.CStruct; import ctypes.java.CType; import ctypes.java.CULong; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class SecurityInteger extends CStruct { /* * typedef struct _SECURITY_INTEGER { unsigned long LowPart; long HighPart; } SECURITY_INTEGER, *PSECURITY_INTEGER; * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public CULong lowPart = new CULong(); public CLong highPart = new CLong(); public SecurityInteger() throws CException { super(); CType[] s = { lowPart, highPart }; setElements(s); } } --- NEW FILE: PCredHandle.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CPointer; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class PCredHandle extends CPointer { public CtxtHandle handle = new CtxtHandle(); public PCredHandle() throws Exception { super(); setSubject(handle); } } --- NEW FILE: SSPI.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CDLL; import ctypes.java.CException; import ctypes.java.CFunction; import ctypes.java.CLong; import ctypes.java.CPointer; import ctypes.java.CString; import ctypes.java.CULong; import ctypes.java.win32.Version; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class SSPI { public static long ISC_REQ_DELEGATE = 0x00000001L; public static long ISC_REQ_MUTUAL_AUTH = 0x00000002L; public static long ISC_REQ_REPLAY_DETECT = 0x00000004L; public static long ISC_REQ_SEQUENCE_DETECT = 0x00000008L; public static long ISC_REQ_CONFIDENTIALITY = 0x00000010L; public static long ISC_REQ_USE_SESSION_KEY = 0x00000020L; public static long ISC_REQ_PROMPT_FOR_CREDS = 0x00000040L; public static long ISC_REQ_USE_SUPPLIED_CREDS = 0x00000080L; public static long ISC_REQ_ALLOCATE_MEMORY = 0x00000100L; public static long ISC_REQ_USE_DCE_STYLE = 0x00000200L; public static long ISC_REQ_DATAGRAM = 0x00000400L; public static long ISC_REQ_CONNECTION = 0x00000800L; public static long ISC_REQ_CALL_LEVEL = 0x00001000L; public static long ISC_REQ_FRAGMENT_SUPPLIED = 0x00002000L; public static long ISC_REQ_EXTENDED_ERROR = 0x00004000L; public static long ISC_REQ_STREAM = 0x00008000L; public static long ISC_REQ_INTEGRITY = 0x00010000L; public static long ISC_REQ_IDENTIFY = 0x00020000L; public static long ISC_REQ_NULL_SESSION = 0x00040000L; public static long ISC_REQ_MANUAL_CRED_VALIDATION = 0x00080000L; public static long ISC_REQ_RESERVED1 = 0x00100000L; public static long ISC_REQ_FRAGMENT_TO_FIT = 0x00200000L; // // Credential Use Flags // public static long SECPKG_CRED_INBOUND = 0x00000001L; public static long SECPKG_CRED_OUTBOUND = 0x00000002L; public static long SECPKG_CRED_BOTH = 0x00000003L; public static long SECPKG_CRED_DEFAULT = 0x00000004L; public static long SECPKG_CRED_RESERVED = 0xF0000000L; public static long SECBUFFER_VERSION =0; public static long SECBUFFER_EMPTY =0; // Undefined, replaced by provider public static long SECBUFFER_DATA =1 ; // Packet data public static long SECBUFFER_TOKEN = 2; // Security token public static long SECBUFFER_PKG_PARAMS = 3; // Package specific parameters public static long SECBUFFER_MISSING = 4 ; // Missing Data indicator public static long SECBUFFER_EXTRA = 5; // Extra data public static long SECBUFFER_STREAM_TRAILER = 7; // Security Header public static long SECBUFFER_NEGOTIATION_INFO = 8; // Hints from the negotiation pkg public static long SECBUFFER_PADDING = 9 ; // non-data padding public static long SECBUFFER_STREAM = 10; // whole encrypted message public static long SECBUFFER_MECHLIST =11; public static long SECBUFFER_MECHLIST_SIGNATURE= 12 ; public static long SECBUFFER_TARGET = 13; public static long SECBUFFER_CHANNEL_BINDINGS =14; public static long SECBUFFER_ATTRMASK =0xF0000000; public static long SECBUFFER_READONLY =0x80000000 ; // Buffer is read-only, no checksum public static long SECBUFFER_READONLY_WITH_CHECKSUM =0x10000000; // Buffer is read-only, and checksummed public static long SECBUFFER_RESERVED =0x60000000; // Flags reserved to security system // // Data Representation Constant: // public static long SECURITY_NATIVE_DREP = 0x00000010; public static long SECURITY_NETWORK_DREP = 0x00000000; static CDLL securityDLL = null; static CDLL getSecurityDLL() throws CException { if (securityDLL == null) { if (Version.isNT()) { securityDLL = CDLL.LoadLibrary("security.DLL"); } else { securityDLL = CDLL.LoadLibrary("secur32.DLL"); } } return securityDLL; } /* * SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA( SEC_CHAR SEC_FAR * pszPrincipal, // Name of principal SEC_CHAR SEC_FAR * pszPackage, // Name of package unsigned long fCredentialUse, // Flags indicating use void SEC_FAR * pvLogonId, // Pointer to logon ID void SEC_FAR * pAuthData, // Package specific data SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey() PCredHandle phCredential, // (out) Cred Handle PTimeStamp ptsExpiry // (out) Lifetime (optional) ); * @author Bradley Schatz * */ public static long AcquireCredentialsHandleA( CString principal, CString packageName, CULong credentialUse, CPointer logonId, CPointer authData, CPointer getKeyFn, CPointer getKeyArgument, CredHandle credential, TimeStamp ptsExpiry) throws CException { CFunction func = CFunction.loadNativeFunction(getSecurityDLL(), "AcquireCredentialsHandleA"); Object[] args = { principal, packageName, credentialUse, logonId, authData, getKeyFn, getKeyArgument, credential, ptsExpiry }; CLong res = (CLong) func.call(CLong.class, args, CFunction.FUNCFLAG_STDCALL); return res.getValue(); } /* * InitializeSecurityContextA( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) SEC_CHAR SEC_FAR * pszTargetName, // Name of target unsigned long fContextReq, // Context Requirements unsigned long Reserved1, // Reserved, MBZ unsigned long TargetDataRep, // Data rep of target PSecBufferDesc pInput, // Input Buffers unsigned long Reserved2, // Reserved, MBZ PCtxtHandle phNewContext, // (out) New Context handle PSecBufferDesc pOutput, // (inout) Output Buffers unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs PTimeStamp ptsExpiry // (out) Life span (OPT) ); * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public static long InitializeSecurityContextA( CredHandle phCredential, // Cred to base context CtxtHandle phContext, // Existing context (OPT) CString pszTargetName, // Name of target CULong fContextReq, // Context Requirements CULong Reserved1, // Reserved, MBZ CULong TargetDataRep, // Data rep of target SecBufferDesc pInput, // Input Buffers CULong Reserved2, // Reserved, MBZ CtxtHandle phNewContext, // (out) New Context handle SecBufferDesc pOutput, // (inout) Output Buffers CULong pfContextAttr, // (out) Context attrs TimeStamp ptsExpiry // (out) Life span (OPT) ) throws CException { CFunction func = CFunction.loadNativeFunction(getSecurityDLL(), "InitializeSecurityContextA"); Object[] args = { phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, new CPointer(pfContextAttr), ptsExpiry }; CLong res = (CLong) func.call(CLong.class, args, CFunction.FUNCFLAG_STDCALL); return res.getValue(); } /* * SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA( SEC_CHAR SEC_FAR * pszPackageName, // Name of package PSecPkgInfoA SEC_FAR *ppPackageInfo // Receives package info ); * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public static long QuerySecurityPackageInfoA(CString pszPackageName, PSecPkgInfoA ppPackageInfo) throws CException { CFunction func = CFunction.loadNativeFunction(getSecurityDLL(), "QuerySecurityPackageInfoA"); Object[] args = { pszPackageName, new CPointer(ppPackageInfo)}; CLong res = (CLong) func.call(CLong.class, args, CFunction.FUNCFLAG_STDCALL); return res.getValue(); } /* * SECURITY_STATUS SEC_ENTRY CompleteAuthToken( PCtxtHandle phContext, // Context to complete PSecBufferDesc pToken // Token to complete ); * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public static long CompleteAuthToken(CtxtHandle phContext, SecBufferDesc pToken) throws CException { CFunction func = CFunction.loadNativeFunction(getSecurityDLL(), "CompleteAuthToken"); Object[] args = { phContext, pToken }; CLong res = (CLong) func.call(CLong.class, args, CFunction.FUNCFLAG_STDCALL); return res.getValue(); } } --- NEW FILE: PSecBuffer.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; import ctypes.java.CPointer; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class PSecBuffer extends CPointer { public SecPkgInfoA handle = new SecPkgInfoA(); public PSecBuffer() throws CException { super(); setSubject(handle); } } --- NEW FILE: TimeStamp.java --- /* * Created on 23/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class TimeStamp extends SecurityInteger { /** * @throws Exception */ public TimeStamp() throws CException { super(); // TODO Auto-generated constructor stub } } --- NEW FILE: SecHandle.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; import ctypes.java.CStruct; import ctypes.java.CType; import ctypes.java.CULong; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class SecHandle extends CStruct { /** * typedef struct _SecHandle { ULONG_PTR dwLower ; ULONG_PTR dwUpper ; } SecHandle, * PSecHandle ; */ public CULong dwLower = new CULong(0); public CULong dwUpper = new CULong(0); public SecHandle() throws CException { super(); CType[] e = { dwLower, dwUpper }; setElements(e); } } --- NEW FILE: CtxtHandle.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class CtxtHandle extends SecHandle { /** * @throws Exception */ public CtxtHandle() throws CException { super(); } } --- NEW FILE: SecPkgInfoA.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CCharPtr; import ctypes.java.CShort; import ctypes.java.CStruct; import ctypes.java.CType; import ctypes.java.CULong; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class SecPkgInfoA extends CStruct { /** * typedef struct _SecPkgInfoA { unsigned long fCapabilities; // Capability bitmask unsigned short wVersion; // Version of driver unsigned short wRPCID; // ID for RPC Runtime unsigned long cbMaxToken; // Size of authentication token (max) #ifdef MIDL_PASS [string] #endif SEC_CHAR SEC_FAR * Name; // Text name #ifdef MIDL_PASS [string] #endif SEC_CHAR SEC_FAR * Comment; // Comment } SecPkgInfoA, SEC_FAR * PSecPkgInfoA; */ public CULong fCapabilities = new CULong(); public CShort wVersion = new CShort(); public CShort wRPCID = new CShort(); public CULong cbMaxToken = new CULong(); public CCharPtr Name = new CCharPtr(); public CCharPtr Comment = new CCharPtr(); public SecPkgInfoA() { super(); CType[] el = { fCapabilities, wVersion , wRPCID , cbMaxToken , Name , Comment }; setElements(el); } } --- NEW FILE: PCtxtHandle.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CPointer; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class PCtxtHandle extends CPointer { public SecHandle handle = new SecHandle(); public PCtxtHandle() throws Exception { super(); setSubject(handle); } } --- NEW FILE: PSecBufferDesc.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CPointer; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class PSecBufferDesc extends CPointer { public SecBufferDesc handle = new SecBufferDesc(); public PSecBufferDesc() throws Exception { super(); setSubject(handle); } } --- NEW FILE: SecBufferDesc.java --- /* * Created on 22/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; import ctypes.java.CStruct; import ctypes.java.CType; import ctypes.java.CULong; /** typedef struct _SecBufferDesc { unsigned long ulVersion; // Version number unsigned long cBuffers; // Number of buffers #ifdef MIDL_PASS [size_is(cBuffers)] #endif PSecBuffer pBuffers; // Pointer to array of buffers } SecBufferDesc, SEC_FAR * PSecBufferDesc; */ public class SecBufferDesc extends CStruct { public CULong ulVersion = new CULong(); public CULong cBuffers = new CULong(); public PSecBuffer pBuffers = new PSecBuffer(); public SecBufferDesc() throws CException { super(); CType[] e = { ulVersion, cBuffers, pBuffers }; setElements(e); } } --- NEW FILE: CredHandle.java --- /* * Created on 23/07/2003 * */ package ctypes.java.win32.sspi; import ctypes.java.CException; /** * @author Bradley Schatz * * Copyright 2003 Managed Data Security */ public class CredHandle extends CtxtHandle { /** * @throws Exception */ public CredHandle() throws CException { super(); // TODO Auto-generated constructor stub } } |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:28:18
|
Update of /cvsroot/ctypes/ctypes-java/src/test/ctypes/java/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19412/src/test/ctypes/java/test Modified Files: TestAllGeneric.java Log Message: Index: TestAllGeneric.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/test/ctypes/java/test/TestAllGeneric.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TestAllGeneric.java 22 Mar 2004 05:33:33 -0000 1.3 --- TestAllGeneric.java 29 Aug 2004 01:28:07 -0000 1.4 *************** *** 23,31 **** package ctypes.java.test; - import ctypes.java.test.generic.*; - import ctypes.java.test.linux.*; - import ctypes.java.test.win32.*; import junit.framework.Test; import junit.framework.TestSuite; /** --- 23,30 ---- package ctypes.java.test; import junit.framework.Test; import junit.framework.TestSuite; + import ctypes.java.test.generic.CharTest; + import ctypes.java.test.generic.PointerTest; /** |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:28:17
|
Update of /cvsroot/ctypes/ctypes-java/src/test/ctypes/java/test/win32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19412/src/test/ctypes/java/test/win32 Modified Files: CallbackTest.java Log Message: Index: CallbackTest.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/test/ctypes/java/test/win32/CallbackTest.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CallbackTest.java 19 Apr 2004 13:39:03 -0000 1.3 --- CallbackTest.java 29 Aug 2004 01:28:06 -0000 1.4 *************** *** 100,104 **** // the arguments to the quicksort function ! Object[] arg = { intArray, // the array to be sorted new CInt(intArray.getLength()), // length of array new CInt(4), // size of array element (in bytes) --- 100,104 ---- // the arguments to the quicksort function ! Object[] args = { intArray, // the array to be sorted new CInt(intArray.getLength()), // length of array new CInt(4), // size of array element (in bytes) *************** *** 106,110 **** // quicksort the ints (call it) ! qsort.call(CInt.class, arg, CFunction.FUNCFLAG_CDECL ); // check that it is sorted. --- 106,110 ---- // quicksort the ints (call it) ! qsort.call(CInt.class, args, CFunction.FUNCFLAG_CDECL ); // check that it is sorted. |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:28:17
|
Update of /cvsroot/ctypes/ctypes-java/src/jni/libffi_msvc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19412/src/jni/libffi_msvc Added Files: types.c win32.c ffitarget.h win32.S README.ctypes ffi_common.h fficonfig.h LICENSE prep_cif.c ffi.h README ffi.c Log Message: --- NEW FILE: ffi_common.h --- /* ----------------------------------------------------------------------- ffi_common.h - Copyright (c) 1996 Red Hat, Inc. Common internal definitions and macros. Only necessary for building libffi. ----------------------------------------------------------------------- */ #ifndef FFI_COMMON_H #define FFI_COMMON_H #ifdef __cplusplus extern "C" { #endif #include <fficonfig.h> /* Do not move this. Some versions of AIX are very picky about where this is positioned. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # if HAVE_ALLOCA_H # include <alloca.h> # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif /* Check for the existence of memcpy. */ #if STDC_HEADERS # include <string.h> #else # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # endif #endif #if defined(FFI_DEBUG) #include <stdio.h> #endif #ifdef FFI_DEBUG /*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); void ffi_stop_here(void); void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); #define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) #define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) #define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) #else #define FFI_ASSERT(x) #define FFI_ASSERT_AT(x, f, l) #define FFI_ASSERT_VALID_TYPE(x) #endif #define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif); /* Extended cif, used in callback from assembly routine */ typedef struct { /*@dependent@*/ ffi_cif *cif; /*@dependent@*/ void *rvalue; /*@dependent@*/ void **avalue; } extended_cif; /* Terse sized type definitions. */ typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); typedef signed int SINT8 __attribute__((__mode__(__QI__))); typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); typedef signed int SINT16 __attribute__((__mode__(__HI__))); typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); typedef signed int SINT32 __attribute__((__mode__(__SI__))); typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); typedef signed int SINT64 __attribute__((__mode__(__DI__))); typedef float FLOAT32; #ifdef __cplusplus } #endif #endif --- NEW FILE: LICENSE --- libffi - Copyright (c) 1996-2003 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for x86 and x86-64. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H /* ---- System specific configurations ----------------------------------- */ #if defined (X86_64) && defined (__i386__) #undef X86_64 #define X86 #endif /* ---- Generic type definitions ----------------------------------------- */ #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, /* ---- Intel x86 Win32 ---------- */ #if defined(X86_WIN32) || defined(_MSC_VER) FFI_SYSV, FFI_STDCALL, /* TODO: Add fastcall support for the sake of completeness */ FFI_DEFAULT_ABI = FFI_SYSV, #endif /* ---- Intel x86 and AMD x86-64 - */ #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) FFI_SYSV, FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ #ifdef __i386__ FFI_DEFAULT_ABI = FFI_SYSV, #else FFI_DEFAULT_ABI = FFI_UNIX64, #endif #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #endif /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 #ifdef X86_64 #define FFI_TRAMPOLINE_SIZE 24 #define FFI_NATIVE_RAW_API 0 #else #ifdef _MSC_VER # define FFI_TRAMPOLINE_SIZE 15 #else # define FFI_TRAMPOLINE_SIZE 10 #endif #define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ #endif #endif --- NEW FILE: win32.S --- /* ----------------------------------------------------------------------- win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. Copyright (c) 2001 John Beniton Copyright (c) 2002 Ranjit Mathew X86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> .text .globl ffi_prep_args # This assumes we are using gas. .balign 16 .globl _ffi_call_SYSV _ffi_call_SYSV: pushl %ebp movl %esp,%ebp # Make room for all of the new args. movl 16(%ebp),%ecx subl %ecx,%esp movl %esp,%eax # Place all of the ffi_prep_args in position pushl 12(%ebp) pushl %eax call *8(%ebp) # Return stack to previous state and call the function addl $8,%esp # FIXME: Align the stack to a 128-bit boundary to avoid # potential performance hits. call *28(%ebp) # Remove the space we pushed for the args movl 16(%ebp),%ecx addl %ecx,%esp # Load %ecx with the return type code movl 20(%ebp),%ecx # If the return value pointer is NULL, assume no return value. cmpl $0,24(%ebp) jne retint # Even if there is no space for the return value, we are # obliged to handle floating-point values. cmpl $FFI_TYPE_FLOAT,%ecx jne noretval fstp %st(0) jmp epilogue retint: cmpl $FFI_TYPE_INT,%ecx jne retfloat # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) jmp epilogue retfloat: cmpl $FFI_TYPE_FLOAT,%ecx jne retdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstps (%ecx) jmp epilogue retdouble: cmpl $FFI_TYPE_DOUBLE,%ecx jne retlongdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpl (%ecx) jmp epilogue retlongdouble: cmpl $FFI_TYPE_LONGDOUBLE,%ecx jne retint64 # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpt (%ecx) jmp epilogue retint64: cmpl $FFI_TYPE_SINT64,%ecx jne retstruct # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) retstruct: # Nothing to do! noretval: epilogue: movl %ebp,%esp popl %ebp ret .ffi_call_SYSV_end: # This assumes we are using gas. .balign 16 .globl _ffi_call_STDCALL _ffi_call_STDCALL: pushl %ebp movl %esp,%ebp # Make room for all of the new args. movl 16(%ebp),%ecx subl %ecx,%esp movl %esp,%eax # Place all of the ffi_prep_args in position pushl 12(%ebp) pushl %eax call *8(%ebp) # Return stack to previous state and call the function addl $8,%esp # FIXME: Align the stack to a 128-bit boundary to avoid # potential performance hits. call *28(%ebp) # stdcall functions pop arguments off the stack themselves # Load %ecx with the return type code movl 20(%ebp),%ecx # If the return value pointer is NULL, assume no return value. cmpl $0,24(%ebp) jne sc_retint # Even if there is no space for the return value, we are # obliged to handle floating-point values. cmpl $FFI_TYPE_FLOAT,%ecx jne sc_noretval fstp %st(0) jmp sc_epilogue sc_retint: cmpl $FFI_TYPE_INT,%ecx jne sc_retfloat # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) jmp sc_epilogue sc_retfloat: cmpl $FFI_TYPE_FLOAT,%ecx jne sc_retdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstps (%ecx) jmp sc_epilogue sc_retdouble: cmpl $FFI_TYPE_DOUBLE,%ecx jne sc_retlongdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpl (%ecx) jmp sc_epilogue sc_retlongdouble: cmpl $FFI_TYPE_LONGDOUBLE,%ecx jne sc_retint64 # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpt (%ecx) jmp sc_epilogue sc_retint64: cmpl $FFI_TYPE_SINT64,%ecx jne sc_retstruct # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) sc_retstruct: # Nothing to do! sc_noretval: sc_epilogue: movl %ebp,%esp popl %ebp ret .ffi_call_STDCALL_end: --- NEW FILE: prep_cif.c --- /* ----------------------------------------------------------------------- prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> /* Round up to FFI_SIZEOF_ARG. */ #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) /* Perform machine independent initialization of aggregate type specifications. */ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) { ffi_type **ptr; FFI_ASSERT(arg != NULL); /*@-usedef@*/ FFI_ASSERT(arg->elements != NULL); FFI_ASSERT(arg->size == 0); FFI_ASSERT(arg->alignment == 0); ptr = &(arg->elements[0]); while ((*ptr) != NULL) { if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; /* Perform a sanity check on the argument type */ FFI_ASSERT_VALID_TYPE(*ptr); arg->size = ALIGN(arg->size, (*ptr)->alignment); arg->size += (*ptr)->size; arg->alignment = (arg->alignment > (*ptr)->alignment) ? arg->alignment : (*ptr)->alignment; ptr++; } /* Structure size includes tail padding. This is important for structures that fit in one register on ABIs like the PowerPC64 Linux ABI that right justify small structs in a register. It's also needed for nested structure layout, for example struct A { long a; char b; }; struct B { struct A x; char y; }; should find y at an offset of 2*sizeof(long) and result in a total size of 3*sizeof(long). */ arg->size = ALIGN (arg->size, arg->alignment); if (arg->size == 0) return FFI_BAD_TYPEDEF; else return FFI_OK; /*@=usedef@*/ } /* Perform machine independent ffi_cif preparation, then call machine dependent routine. */ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, ffi_abi abi, unsigned int nargs, /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, /*@dependent@*/ ffi_type **atypes) { unsigned bytes = 0; unsigned int i; ffi_type **ptr; FFI_ASSERT(cif != NULL); FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); cif->abi = abi; cif->arg_types = atypes; cif->nargs = nargs; cif->rtype = rtype; cif->flags = 0; /* Initialize the return type if necessary */ /*@-usedef@*/ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; /*@=usedef@*/ /* Perform a sanity check on the return type */ FFI_ASSERT_VALID_TYPE(cif->rtype); /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ #if !defined M68K && !defined __x86_64__ && !defined S390 /* Make space for the return structure pointer */ if (cif->rtype->type == FFI_TYPE_STRUCT #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) { /* Initialize any uninitialized aggregate type definitions */ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; /* Perform a sanity check on the argument type, do this check after the initialization. */ FFI_ASSERT_VALID_TYPE(*ptr); #if !defined __x86_64__ && !defined S390 #ifdef SPARC if (((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 16 || cif->abi != FFI_V9)) || ((*ptr)->type == FFI_TYPE_LONGDOUBLE && cif->abi != FFI_V9)) bytes += sizeof(void*); else #endif { #ifndef _MSC_VER /* Don't know if this is a libffi bug or not. At least on Windows with MSVC, function call parameters are *not* aligned in the same way as structure fields are, they are only aligned in integer boundaries. This doesn't do any harm for cdecl functions and closures, since the caller cleans up the stack, but it is wrong for stdcall functions where the callee cleans. */ /* Add any padding if necessary */ if (((*ptr)->alignment - 1) & bytes) bytes = ALIGN(bytes, (*ptr)->alignment); #endif bytes += STACK_ARG_SIZE((*ptr)->size); } #endif } cif->bytes = bytes; /* Perform machine dependent cif processing */ return ffi_prep_cif_machdep(cif); } --- NEW FILE: fficonfig.h --- /* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */ /* fficonfig.h. Generated automatically by configure. */ /* fficonfig.h.in. Generated automatically from configure.in by autoheader. */ /* Defines for MSVC */ #define __attribute__(x) /* */ #define alloca _alloca /*----------------------------------------------------------------*/ /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define if you have alloca, as a function or macro. */ #define HAVE_ALLOCA 1 /* Define if you have <alloca.h> and it should be used (not on Ultrix). */ /* #define HAVE_ALLOCA_H 1 */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you have the memcpy function. */ #define HAVE_MEMCPY 1 /* Define if read-only mmap of a plain file works. */ //#define HAVE_MMAP_FILE 1 /* Define if mmap of /dev/zero works. */ //#define HAVE_MMAP_DEV_ZERO 1 /* Define if mmap with MAP_ANON(YMOUS) works. */ //#define HAVE_MMAP_ANON 1 /* The number of bytes in type double */ #define SIZEOF_DOUBLE 8 /* The number of bytes in type long double */ #define SIZEOF_LONG_DOUBLE 12 /* Define if you have the long double type and it is bigger than a double */ #define HAVE_LONG_DOUBLE 1 /* whether byteorder is bigendian */ /* #undef WORDS_BIGENDIAN */ /* Define if the host machine stores words of multi-word integers in big-endian order. */ /* #undef HOST_WORDS_BIG_ENDIAN */ /* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ #define BYTEORDER 1234 /* Define if your assembler and linker support unaligned PC relative relocs. */ /* #undef HAVE_AS_SPARC_UA_PCREL */ /* Define if your assembler supports .register. */ /* #undef HAVE_AS_REGISTER_PSEUDO_OP */ /* Define if .eh_frame sections should be read-only. */ /* #undef HAVE_RO_EH_FRAME */ /* Define to the flags needed for the .section .eh_frame directive. */ /* #define EH_FRAME_FLAGS "aw" */ /* Define to the flags needed for the .section .eh_frame directive. */ /* #define EH_FRAME_FLAGS "aw" */ /* Define this if you want extra debugging. */ /* #undef FFI_DEBUG */ /* Define this is you do not want support for aggregate types. */ /* #undef FFI_NO_STRUCTS */ /* Define this is you do not want support for the raw API. */ /* #undef FFI_NO_RAW_API */ /* Define this if you are using Purify and want to suppress spurious messages. */ /* #undef USING_PURIFY */ --- NEW FILE: README.ctypes --- The purpose is to hack the libffi sources so that they can be compiled with MSVC, and to extend them so that they have the features I need for ctypes. I retrieved the libffi sources from the gcc cvs repository on 2004-01-27. Then I did 'configure' in a 'build' subdirectory on a x86 linux system, and copied the files I found useful. --- NEW FILE: ffi.c --- /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. Copyright (c) 2002 Ranjit Mathew Copyright (c) 2002 Bo Thorsen Copyright (c) 2002 Roger Sayle x86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef __x86_64__ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ /*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) /*@=exportheader@*/ { register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; argp = stack; if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) { *(void **) argp = ecif->rvalue; argp += 4; } p_argv = ecif->avalue; for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++) { size_t z; /* Align if necessary */ if ((sizeof(int) - 1) & (unsigned) argp) argp = (char *) ALIGN(argp, sizeof(int)); z = (*p_arg)->size; if (z < sizeof(int)) { z = sizeof(int); switch ((*p_arg)->type) { case FFI_TYPE_SINT8: *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); break; case FFI_TYPE_UINT8: *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); break; case FFI_TYPE_SINT16: *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); break; case FFI_TYPE_UINT16: *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); break; case FFI_TYPE_SINT32: *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); break; case FFI_TYPE_UINT32: *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); break; case FFI_TYPE_STRUCT: *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); break; default: FFI_ASSERT(0); } } else { memcpy(argp, *p_argv, z); } p_argv++; argp += z; } return; } /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { /* Set the return type flag */ switch (cif->rtype->type) { case FFI_TYPE_VOID: case FFI_TYPE_STRUCT: case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: cif->flags = (unsigned) cif->rtype->type; break; case FFI_TYPE_UINT64: cif->flags = FFI_TYPE_SINT64; break; default: cif->flags = FFI_TYPE_INT; break; } return FFI_OK; } /*@-declundef@*/ /*@-exportheader@*/ #ifdef _MSC_VER extern int #else extern void #endif ffi_call_SYSV(void (*)(char *, extended_cif *), /*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ #if defined(X86_WIN32) || defined(_MSC_VER) /*@-declundef@*/ /*@-exportheader@*/ #ifdef _MSC_VER extern int #else extern void #endif ffi_call_STDCALL(void (*)(char *, extended_cif *), /*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ #endif /* X86_WIN32 || _MSC_VER*/ #ifdef _MSC_VER int #else void #endif ffi_call(/*@dependent@*/ ffi_cif *cif, void (*fn)(), /*@out@*/ void *rvalue, /*@dependent@*/ void **avalue) { extended_cif ecif; ecif.cif = cif; ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; switch (cif->abi) { case FFI_SYSV: /*@-usedef@*/ #ifdef _MSC_VER return #endif ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; #if defined(X86_WIN32) || defined(_MSC_VER) case FFI_STDCALL: /*@-usedef@*/ #ifdef _MSC_VER return #endif ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; #endif /* X86_WIN32 */ default: FFI_ASSERT(0); break; } return -1; /* theller: Hrm. */ } /** private members **/ static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); #ifndef _MSC_VER static void ffi_closure_SYSV (ffi_closure *) __attribute__ ((regparm(1))); static void ffi_closure_raw_SYSV (ffi_raw_closure *) __attribute__ ((regparm(1))); #endif /* This function is jumped to by the trampoline */ #ifdef _MSC_VER static void __fastcall ffi_closure_SYSV (ffi_closure *closure, int *argp) #else static void ffi_closure_SYSV (closure) ffi_closure *closure; #endif { // this is our return value storage long double res; // our various things... ffi_cif *cif; void **arg_area; unsigned short rtype; void *resp = (void*)&res; #ifdef _MSC_VER void *args = &argp[1]; #else void *args = __builtin_dwarf_cfa (); #endif cif = closure->cif; arg_area = (void**) alloca (cif->nargs * sizeof (void*)); /* this call will initialize ARG_AREA, such that each * element in that array points to the corresponding * value on the stack; and if the function returns * a structure, it will re-set RESP to point to the * structure return address. */ ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); (closure->fun) (cif, resp, arg_area, closure->user_data); rtype = cif->flags; #ifdef _MSC_VER /* now, do a generic return based on the value of rtype */ if (rtype == FFI_TYPE_INT) { _asm mov eax, resp ; _asm mov eax, [eax] ; } else if (rtype == FFI_TYPE_FLOAT) { _asm mov eax, resp ; _asm fld DWORD PTR [eax] ; // asm ("flds (%0)" : : "r" (resp) : "st" ); } else if (rtype == FFI_TYPE_DOUBLE) { _asm mov eax, resp ; _asm fld QWORD PTR [eax] ; // asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_LONGDOUBLE) { // asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_SINT64) { _asm mov edx, resp ; _asm mov eax, [edx] ; _asm mov edx, [edx + 4] ; // asm ("movl 0(%0),%%eax;" // "movl 4(%0),%%edx" // : : "r"(resp) // : "eax", "edx"); } #else /* now, do a generic return based on the value of rtype */ if (rtype == FFI_TYPE_INT) { asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); } else if (rtype == FFI_TYPE_FLOAT) { asm ("flds (%0)" : : "r" (resp) : "st" ); } else if (rtype == FFI_TYPE_DOUBLE) { asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_LONGDOUBLE) { asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_SINT64) { asm ("movl 0(%0),%%eax;" "movl 4(%0),%%edx" : : "r"(resp) : "eax", "edx"); } #endif } /*@-exportheader@*/ static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ffi_cif *cif) /*@=exportheader@*/ { register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; argp = stack; if ( cif->rtype->type == FFI_TYPE_STRUCT ) { *rvalue = *(void **) argp; argp += 4; } p_argv = avalue; for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) { size_t z; /* Align if necessary */ if ((sizeof(int) - 1) & (unsigned) argp) { argp = (char *) ALIGN(argp, sizeof(int)); } z = (*p_arg)->size; /* because we're little endian, this is what it turns into. */ *p_argv = (void*) argp; p_argv++; argp += z; } return; } /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ /* MOV EDX, ESP is 0x8b 0xd4 */ #ifdef _MSC_VER #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - ((unsigned int) __tramp + 8 + 4); \ *(unsigned char*) &__tramp[0] = 0xb9; \ *(unsigned int*) &__tramp[1] = __ctx; /* mov ecx, __ctx */ \ *(unsigned char*) &__tramp[5] = 0x8b; \ *(unsigned char*) &__tramp[6] = 0xd4; \ *(unsigned char*) &__tramp[7] = 0xe8; \ *(unsigned int*) &__tramp[8] = __dis; /* call __fun */ \ *(unsigned char*) &__tramp[12] = 0xC2; /* ret BYTES */ \ *(unsigned short*) &__tramp[13] = BYTES; \ } #else #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \ *(unsigned char*) &__tramp[0] = 0xb8; \ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned char *) &__tramp[5] = 0xe9; \ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ }) #endif /* the cif must already be prep'ed */ ffi_status ffi_prep_closure (ffi_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data) { short bytes; FFI_ASSERT (cif->abi == FFI_SYSV); if (cif->abi == FFI_SYSV) bytes = 0; #ifdef _MSC_VER else if (cif->abi == FFI_STDCALL) bytes = cif->bytes; #endif else return FFI_BAD_ABI; FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, (void*)closure, bytes); closure->cif = cif; closure->user_data = user_data; closure->fun = fun; return FFI_OK; } #endif /* __x86_64__ */ --- NEW FILE: win32.c --- /* ----------------------------------------------------------------------- win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. Copyright (c) 2001 John Beniton Copyright (c) 2002 Ranjit Mathew X86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ /* theller: almost verbatim translation from gas syntax to MSVC inline assembler code. */ /* theller: ffi_call_SYSV and ffi_call_STDCALL now return an integer - the difference of the stack pointer before and after the function call. If everything is ok, zero is returned. If stdcall functions are passed the wrong number of arguments, the difference will be nonzero. */ #include <ffi.h> #include <ffi_common.h> __declspec(naked) int ffi_call_SYSV(void (* prepfunc)(char *, extended_cif *), /* 8 */ extended_cif *ecif, /* 12 */ unsigned bytes, /* 16 */ unsigned flags, /* 20 */ unsigned *rvalue, /* 24 */ void (*fn)()) /* 28 */ { _asm { push ebp mov ebp, esp push esi // NEW: this register must be preserved across function calls // XXX SAVE ESP NOW! mov esi, esp // save stack pointer before the call // Make room for all of the new args. mov ecx, [ebp+16] sub esp, ecx // sub esp, bytes mov eax, esp // Place all of the ffi_prep_args in position push [ebp + 12] // ecif push eax call [ebp + 8] // prepfunc // Return stack to previous state and call the function add esp, 8 // FIXME: Align the stack to a 128-bit boundary to avoid // potential performance hits. call [ebp + 28] // Remove the space we pushed for the args mov ecx, [ebp + 16] add esp, ecx // XXX ASSERT THAT ESP IS THE SAME NOW THAN BEFORE! sub esi, esp // Load %ecx with the return type code mov ecx, [ebp + 20] // If the return value pointer is NULL, assume no return value. /* Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, otherwise only one BYTE will be compared (instead of a DWORD)! */ cmp DWORD PTR [ebp + 24], 0 jne sc_retint // Even if there is no space for the return value, we are // obliged to handle floating-point values. cmp ecx, FFI_TYPE_FLOAT jne sc_noretval // fstp %st(0) fstp st(0) jmp sc_epilogue sc_retint: cmp ecx, FFI_TYPE_INT jne sc_retfloat // # Load %ecx with the pointer to storage for the return value mov ecx, [ebp + 24] mov [ecx + 0], eax jmp sc_epilogue sc_retfloat: cmp ecx, FFI_TYPE_FLOAT jne sc_retdouble // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstps (%ecx) fstp DWORD PTR [ecx] jmp sc_epilogue sc_retdouble: cmp ecx, FFI_TYPE_DOUBLE jne sc_retlongdouble // movl 24(%ebp),%ecx mov ecx, [ebp+24] fstp QWORD PTR [ecx] jmp sc_epilogue jmp sc_retlongdouble // avoid warning about unused label sc_retlongdouble: cmp ecx, FFI_TYPE_LONGDOUBLE jne sc_retint64 // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstpt (%ecx) fstp QWORD PTR [ecx] /* XXX ??? */ jmp sc_epilogue sc_retint64: cmp ecx, FFI_TYPE_SINT64 jne sc_retstruct // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] mov [ecx+0], eax mov [ecx+4], edx sc_retstruct: // Nothing to do! sc_noretval: sc_epilogue: mov eax, esi pop esi // NEW restore: must be preserved across function calls mov esp, ebp pop ebp ret } } __declspec(naked) int ffi_call_STDCALL(void (* prepfunc)(char *, extended_cif *), /* 8 */ extended_cif *ecif, /* 12 */ unsigned bytes, /* 16 */ unsigned flags, /* 20 */ unsigned *rvalue, /* 24 */ void (*fn)()) /* 28 */ { _asm { push ebp mov ebp, esp push esi // NEW: this register must be preserved across function calls // XXX SAVE ESP NOW! mov esi, esp // Make room for all of the new args. mov ecx, [ebp+16] sub esp, ecx mov eax, esp // Place all of the ffi_prep_args in position push [ebp + 12] // ecif push eax call [ebp + 8] // prepfunc // Return stack to previous state and call the function add esp, 8 // FIXME: Align the stack to a 128-bit boundary to avoid // potential performance hits. call [ebp + 28] // stdcall functions pop arguments off the stack themselves // XXX IS ESP NOW THE SAME AS BEFORE? sub esi, esp // Load %ecx with the return type code mov ecx, [ebp + 20] // If the return value pointer is NULL, assume no return value. /* Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, otherwise only one BYTE will be compared (instead of a DWORD)! */ cmp DWORD PTR [ebp + 24], 0 jne sc_retint // Even if there is no space for the return value, we are // obliged to handle floating-point values. cmp ecx, FFI_TYPE_FLOAT jne sc_noretval // fstp %st(0) fstp st(0) jmp sc_epilogue sc_retint: cmp ecx, FFI_TYPE_INT jne sc_retfloat // # Load %ecx with the pointer to storage for the return value mov ecx, [ebp + 24] mov [ecx + 0], eax jmp sc_epilogue sc_retfloat: cmp ecx, FFI_TYPE_FLOAT jne sc_retdouble // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstps (%ecx) fstp DWORD PTR [ecx] jmp sc_epilogue sc_retdouble: cmp ecx, FFI_TYPE_DOUBLE jne sc_retlongdouble // movl 24(%ebp),%ecx mov ecx, [ebp+24] fstp QWORD PTR [ecx] jmp sc_epilogue jmp sc_retlongdouble // avoid warning about unused label sc_retlongdouble: cmp ecx, FFI_TYPE_LONGDOUBLE jne sc_retint64 // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstpt (%ecx) fstp QWORD PTR [ecx] /* XXX ??? */ jmp sc_epilogue sc_retint64: cmp ecx, FFI_TYPE_SINT64 jne sc_retstruct // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] mov [ecx+0], eax mov [ecx+4], edx sc_retstruct: // Nothing to do! sc_noretval: sc_epilogue: mov eax, esi pop esi // NEW restore: must be preserved across function calls mov esp, ebp pop ebp ret } } --- NEW FILE: README --- This directory contains the libffi package, which is not part of GCC but shipped with GCC as convenience. Status ====== libffi-2.00 has not been released yet! This is a development snapshot! libffi-1.20 was released on October 5, 1998. Check the libffi web page for updates: <URL:http://sources.redhat.com/libffi/>. What is libffi? =============== Compilers for high level languages generate code that follow certain conventions. These conventions are necessary, in part, for separate compilation to work. One such convention is the "calling convention". The "calling convention" is essentially a set of assumptions made by the compiler about where function arguments will be found on entry to a function. A "calling convention" also specifies where the return value for a function is found. Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. Libffi can be used in such programs to provide a bridge from the interpreter program to compiled code. The libffi library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time. Ffi stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The libffi library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above libffi that handles type conversions for values passed between the two languages. Supported Platforms and Prerequisites ===================================== Libffi has been ported to: SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9) Irix 5.3 & 6.2 (System V/o32 & n32) Intel x86 - Linux (System V ABI) Alpha - Linux and OSF/1 m68k - Linux (System V ABI) PowerPC - Linux (System V ABI, Darwin, AIX) ARM - Linux (System V ABI) Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are that other versions will work. Libffi has also been built and tested with the SGI compiler tools. On PowerPC, the tests failed (see the note below). You must use GNU make to build libffi. SGI's make will not work. Sun's probably won't either. If you port libffi to another platform, please let me know! I assume that some will be easy (x86 NetBSD), and others will be more difficult (HP). Installing libffi ================= [Note: before actually performing any of these installation steps, you may wish to read the "Platform Specific Notes" below.] First you must configure the distribution for your particular system. Go to the directory you wish to build libffi in and run the "configure" program found in the root directory of the libffi source distribution. You may want to tell configure where to install the libffi library and header files. To do that, use the --prefix configure switch. Libffi will install under /usr/local by default. If you want to enable extra run-time debugging checks use the the --enable-debug configure switch. This is useful when your program dies mysteriously while using libffi. Another useful configure switch is --enable-purify-safety. Using this will add some extra code which will suppress certain warnings when you are using Purify with libffi. Only use this switch when using Purify, as it will slow down the library. Configure has many other options. Use "configure --help" to see them all. Once configure has finished, type "make". Note that you must be using GNU make. SGI's make will not work. Sun's probably won't either. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu. To ensure that libffi is working as advertised, type "make test". To install the library and header files, type "make install". Using libffi ============ The Basics ---------- Libffi assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function. The first thing you must do is create an ffi_cif object that matches the signature of the function you wish to call. The cif in ffi_cif stands for Call InterFace. To prepare a call interface object, use the following function: ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes); CIF is a pointer to the call interface object you wish to initialize. ABI is an enum that specifies the calling convention to use for the call. FFI_DEFAULT_ABI defaults to the system's native calling convention. Other ABI's may be used with care. They are system specific. NARGS is the number of arguments this function accepts. libffi does not yet support vararg functions. RTYPE is a pointer to an ffi_type structure that represents the return type of the function. Ffi_type objects describe the types of values. libffi provides ffi_type objects for many of the native C types: signed int, unsigned int, signed char, unsigned char, etc. There is also a pointer ffi_type object and a void ffi_type. Use &ffi_type_void for functions that don't return values. ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long. If NARGS is 0, this is ignored. ffi_prep_cif will return a status code that you are responsible for checking. It will be one of the following: FFI_OK - All is good. FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif came across is bad. Before making the call, the VALUES vector should be initialized with pointers to the appropriate argument values. To call the the function using the initialized ffi_cif, use the ffi_call function: void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); CIF is a pointer to the ffi_cif initialized specifically for this function. FN is a pointer to the function you want to call. RVALUE is a pointer to a chunk of memory that is to hold the result of the function call. Currently, it must be at least one word in size (except for the n32 version under Irix 6.x, which must be a pointer to an 8 byte aligned value (a long long). It must also be at least word aligned (depending on the return type, and the system's alignment requirements). If RTYPE is &ffi_type_void, this is ignored. If RVALUE is NULL, the return value is discarded. AVALUES is a vector of void* that point to the memory locations holding the argument values for a call. If NARGS is 0, this is ignored. If you are expecting a return value from FN it will have been stored at RVALUE. An Example ---------- Here is a trivial example that calls puts() a few times. #include <stdio.h> #include <ffi.h> int main() { ffi_cif cif; ffi_type *args[1]; void *values[1]; char *s; int rc; /* Initialize the argument info vectors */ args[0] = &ffi_type_uint; values[0] = &s; /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args) == FFI_OK) { s = "Hello World!"; ffi_call(&cif, puts, &rc, values); /* rc now holds the result of the call to puts */ /* values holds a pointer to the function's arg, so to call puts() again all we need to do is change the value of s */ s = "This is cool!"; ffi_call(&cif, puts, &rc, values); } return 0; } Aggregate Types --------------- Although libffi has no special support for unions or bit-fields, it is perfectly happy passing structures back and forth. You must first describe the structure to libffi by creating a new ffi_type object for it. Here is the definition of ffi_type: typedef struct _ffi_type { unsigned size; short alignment; short type; struct _ffi_type **elements; } ffi_type; All structures must have type set to FFI_TYPE_STRUCT. You may set size and alignment to 0. These will be calculated and reset to the appropriate values by ffi_prep_cif(). elements is a NULL terminated array of pointers to ffi_type objects that describe the type of the structure elements. These may, in turn, be structure elements. The following example initializes a ffi_type object representing the tm struct from Linux's time.h: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; /* Those are for future use. */ long int __tm_gmtoff__; __const char *__tm_zone__; }; { ffi_type tm_type; ffi_type *tm_type_elements[12]; int i; tm_type.size = tm_type.alignment = 0; tm_type.elements = &tm_type_elements; for (i = 0; i < 9; i++) tm_type_elements[i] = &ffi_type_sint; tm_type_elements[9] = &ffi_type_slong; tm_type_elements[10] = &ffi_type_pointer; tm_type_elements[11] = NULL; /* tm_type can now be used to represent tm argument types and return types for ffi_prep_cif() */ } Platform Specific Notes ======================= Intel x86 --------- There are no known problems with the x86 port. Sun SPARC - SunOS 4.1.3 & Solaris 2.x ------------------------------------- You must use GNU Make to build libffi on Sun platforms. MIPS - Irix 5.3 & 6.x --------------------- Irix 6.2 and better supports three different calling conventions: o32, n32 and n64. Currently, libffi only supports both o32 and n32 under Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be configured for whichever calling convention it was built for. By default, the configure script will try to build libffi with the GNU development tools. To build libffi with the SGI development tools, set the environment variable CC to either "cc -32" or "cc -n32" before running configure under Irix 6.x (depending on whether you want an o32 or n32 library), or just "cc" for Irix 5.3. With the n32 calling convention, when returning structures smaller than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned. Here's one way of forcing this: double struct_storage[2]; my_small_struct *s = (my_small_struct *) struct_storage; /* Use s for RVALUE */ If you don't do this you are liable to get spurious bus errors. "long long" values are not supported yet. You must use GNU Make to build libffi on SGI platforms. ARM - System V ABI ------------------ The ARM port was performed on a NetWinder running ARM Linux ELF (2.0.31) and gcc 2.8.1. PowerPC System V ABI -------------------- There are two `System V ABI's which libffi implements for PowerPC. They differ only in how small structures are returned from functions. In the FFI_SYSV version, structures that are 8 bytes or smaller are returned in registers. This is what GCC does when it is configured for solaris, and is what the System V ABI I have (dated September 1995) says. In the FFI_GCC_SYSV version, all structures are returned the same way: by passing a pointer as the first argument to the function. This is what GCC does when it is configured for linux or a generic sysv target. EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a inconsistency with the SysV ABI: When a procedure is called with many floating-point arguments, some of them get put on the stack. They are all supposed to be stored in double-precision format, even if they are only single-precision, but EGCS stores single-precision arguments as single-precision anyway. This causes one test to fail (the `many arguments' test). What's With The Crazy Comments? =============================== You might notice a number of cryptic comments in the code, delimited by /*@ and @*/. These are annotations read by the program LCLint, a tool for statically checking C programs. You can read all about it at <http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>. History ======= 1.20 Oct-5-98 Raffaele Sena produces ARM port. 1.19 Oct-5-98 Fixed x86 long double and long long return support. m68k bug fixes from Andreas Schwab. Patch for DU assembler compatibility for the Alpha from Richard Henderson. 1.18 Apr-17-98 Bug fixes and MIPS configuration changes. 1.17 Feb-24-98 Bug fixes and m68k port from Andreas Schwab. PowerPC port from Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. 1.16 Feb-11-98 Richard Henderson produces Alpha port. 1.15 Dec-4-97 Fixed an n32 ABI bug. New libtool, auto* support. 1.14 May-13-97 libtool is now used to generate shared and static libraries. Fixed a minor portability problem reported by Russ McManus <mc...@eq...>. 1.13 Dec-2-96 Added --enable-purify-safety to keep Purify from complaining about certain low level code. Sparc fix for calling functions with < 6 args. Linux x86 a.out fix. 1.12 Nov-22-96 Added missing ffi_type_void, needed for supporting void return types. Fixed test case for non MIPS machines. Cygnus Support is now Cygnus Solutions. 1.11 Oct-30-96 Added notes about GNU make. 1.10 Oct-29-96 Added configuration fix for non GNU compilers. 1.09 Oct-29-96 Added --enable-debug configure switch. Clean-ups based on LCLint feedback. ffi_mips.h is always installed. Many configuration fixes. Fixed ffitest.c for sparc builds. 1.08 Oct-15-96 Fixed n32 problem. Many clean-ups. 1.07 Oct-14-96 Gordon Irlam rewrites v8.S again. Bug fixes. 1.06 Oct-14-96 Gordon Irlam improved the sparc port. 1.05 Oct-14-96 Interface changes based on feedback. 1.04 Oct-11-96 Sparc port complete (modulo struct passing bug). 1.03 Oct-10-96 Passing struct args, and returning struct values works for all architectures/calling conventions. Expanded tests. 1.02 Oct-9-96 Added SGI n32 support. Fixed bugs in both o32 and Linux support. Added "make test". 1.01 Oct-8-96 Fixed float passing bug in mips version. Restructured some of the code. Builds cleanly with SGI tools. 1.00 Oct-7-96 First release. No public announcement. Authors & Credits ================= libffi was written by Anthony Green <gr...@cy...>. Portions of libffi were derived from Gianni Mariani's free gencall library for Silicon Graphics machines. The closure mechanism was designed and implemented by Kresten Krab Thorup. The Sparc port was derived from code contributed by the fine folks at Visible Decisions Inc <http://www.vdi.com>. Further enhancements were made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>. The Alpha port was written by Richard Henderson at Cygnus Solutions. Andreas Schwab ported libffi to m68k Linux and provided a number of bug fixes. Geoffrey Keating ported libffi to the PowerPC. Raffaele Sena ported libffi to the ARM. Jesper Skov and Andrew Haley both did more than their fair share of stepping through the code and tracking down bugs. Thanks also to Tom Tromey for bug fixes and configuration help. Thanks to Jim Blandy, who provided some useful feedback on the libffi interface. If you have a problem, or have found a bug, please send a note to gr...@cy.... --- NEW FILE: types.c --- /* ----------------------------------------------------------------------- types.c - Copyright (c) 1996, 1998 Red Hat, Inc. Predefined ffi_types needed by libffi. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> /* Type definitions */ #define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } #define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } /* Size and alignment are fake here. They must not be 0. */ FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); #if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ || defined IA64 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); #else FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); #endif #if defined X86 || defined X86_WIN32 || defined ARM || defined M68K FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); #elif defined SH FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); #else FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); #endif #if defined X86 || defined X86_WIN32 || defined M68K FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); #elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); #elif defined SPARC FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); #ifdef SPARC64 FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); #else FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); #endif #elif defined X86_64 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); #else FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); #endif --- NEW FILE: ffi.h --- /* -----------------------------------------------------------------*-C-*- libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ /* ------------------------------------------------------------------- The basic API is described in the README file. The raw API is designed to bypass some of the argument packing and unpacking on architectures for which it can be avoided. The closure API allows interpreted functions to be packaged up inside a C function pointer, so that they can be called as C functions, with no understanding on the client side that they are interpreted. It can also be used in other cases in which it is necessary to package up a user specified parameter and a function poi... [truncated message content] |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:27:39
|
Update of /cvsroot/ctypes/ctypes-java In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19327 Modified Files: TODO.txt README.txt INSTALL NEWS.txt Log Message: Index: TODO.txt =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/TODO.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TODO.txt 22 Mar 2004 05:55:36 -0000 1.3 --- TODO.txt 29 Aug 2004 01:27:25 -0000 1.4 *************** *** 1,4 **** - In order of priorities. - Use of JNI strings needs review wrt reference freeing. --- 1,2 ---- *************** *** 11,16 **** configure based build for UNIX. - Integration with ctypes python. - The rest of the U*** types supported by ctypes/python --- 9,12 ---- *************** *** 21,23 **** Port for 64bit systems. ! Use NIO buffers for CTypes on 1.4 VM's. ?Any benefit to this? \ No newline at end of file --- 17,19 ---- Port for 64bit systems. ! Use NIO buffers for CTypes on 1.4 VM's. \ No newline at end of file Index: NEWS.txt =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/NEWS.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NEWS.txt 22 Mar 2004 05:55:36 -0000 1.2 --- NEWS.txt 29 Aug 2004 01:27:25 -0000 1.3 *************** *** 1,4 **** --- 1,9 ---- ctypes.java News - + Version 0.7, 29 Aug, 2004 + Synchronized FFI code with ctypes-python 0.9.1 + Example Windows GUI API Application from JAWIN included + Example NTLM authentication code + integration with commons-httpclisnt + Version 0.2, 22 Mar, 2004 Callbacks working for Win32. Index: INSTALL =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/INSTALL,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** INSTALL 23 Mar 2004 21:41:25 -0000 1.1 --- INSTALL 29 Aug 2004 01:27:25 -0000 1.2 *************** *** 1,7 **** ! ! ! Debugging. ! ! Good article here for linux based debugging. http://www-106.ibm.com/developerworks/java/library/j-jnidebug/ \ No newline at end of file --- 1,4 ---- + See the website. ! To debug, see a good article here for linux based JNI debugging. http://www-106.ibm.com/developerworks/java/library/j-jnidebug/ \ No newline at end of file Index: README.txt =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/README.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** README.txt 22 Mar 2004 05:55:36 -0000 1.2 --- README.txt 29 Aug 2004 01:27:25 -0000 1.3 *************** *** 1,13 **** ! ctypes.java is a java library and native library allowing the creation and ! manipulation of C data types in java. These can then be passed to C-functions ! loaded from dynamic link libraries. ! ! The C-layer elements of this package, and also much of the text you are reading now, ! are largely derived from Thomas Heller's Python ctypes implementation. It in turn is ! supposed to be a greatly enhanced and much more complete replacement of Sam Rushing's ! Python calldll/npstruct/windll modules. ctypes is not based on Sam's work, it has ! different roots. ! This java implementation is intended to do a number of things. * Allow calling native c/c++ fuctions underlying your java platform of choice * Further provide a basis for COM interopability with java. --- 1,7 ---- ! ctypes4j is a java/C framework allowing the creation and manipulation of C data types, ! and calling arbitraty C functions in java, without the need for using JNI. Provision for ! loading and accessing functions from windows DLL's and UNIX shared libraries is included. ! This java implementation enables the following: * Allow calling native c/c++ fuctions underlying your java platform of choice * Further provide a basis for COM interopability with java. *************** *** 23,35 **** however the JNI layer will need some tweaking to get this to work. Read the docs for some examples of how to use this. Further, the unit tests will be your best bet for more advanced usage. ! Current version: 0.1.0 ! Homepage: http://xxx License: MIT ! Platforms: Windows --- 17,35 ---- however the JNI layer will need some tweaking to get this to work. + The C-layer elements of this package, and also much of the text you are reading now, + are largely derived from Thomas Heller's Python ctypes implementation. It in turn is + a greatly enhanced and much more complete replacement of Sam Rushing's + Python calldll/npstruct/windll modules. ctypes is not based on Sam's work, it has + different roots. + Read the docs for some examples of how to use this. Further, the unit tests will be your best bet for more advanced usage. ! Current version: 0.7.0 ! Homepage: http://ctypes4j.sourceforge.net/ License: MIT ! Platforms: Windows, Linux |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:25:41
|
Update of /cvsroot/ctypes/ctypes-java/src/java/ctypes/java In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18970/src/java/ctypes/java Modified Files: CType.java CException.java CBuffer.java CCallbackFunction.java CFunction.java CStruct.java Log Message: Index: CException.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/CException.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CException.java 5 Aug 2003 22:54:59 -0000 1.1 --- CException.java 29 Aug 2004 01:25:28 -0000 1.2 *************** *** 45,47 **** --- 45,62 ---- } + /** + * @param arg0 + * @param arg1 + */ + public CException(String arg0, Throwable arg1) { + super(arg0, arg1); + // TODO Auto-generated constructor stub + } + /** + * @param arg0 + */ + public CException(Throwable arg0) { + super(arg0); + // TODO Auto-generated constructor stub + } } Index: CBuffer.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/CBuffer.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CBuffer.java 22 Mar 2004 05:55:36 -0000 1.3 --- CBuffer.java 29 Aug 2004 01:25:28 -0000 1.4 *************** *** 82,86 **** super.dump(buf, level); for (int j = 0; j < level + 1; j++) { ! buf.append("\t"); } byte[] dt = getData(); --- 82,86 ---- super.dump(buf, level); for (int j = 0; j < level + 1; j++) { ! buf.append("\n"); } byte[] dt = getData(); Index: CCallbackFunction.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/CCallbackFunction.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CCallbackFunction.java 21 Mar 2004 23:44:58 -0000 1.4 --- CCallbackFunction.java 29 Aug 2004 01:25:28 -0000 1.5 *************** *** 11,18 **** public abstract Class[] getConverters(); public abstract Class getResultType(); ! abstract public CReturnable call(CType[] args); public CCallbackFunction() { Class[] converters = getConverters(); int numBytes = 0; --- 11,19 ---- public abstract Class[] getConverters(); public abstract Class getResultType(); ! long thunk; abstract public CReturnable call(CType[] args); public CCallbackFunction() { + super(4); Class[] converters = getConverters(); int numBytes = 0; *************** *** 22,28 **** } } ! this.address = init(getResultType(), getConverters(), numBytes, CFunction.FUNCFLAG_CDECL ); ! this.memoryBacked = true; ! this.isAtomic = true; } --- 23,29 ---- } } ! this.thunk = init(getResultType(), getConverters(), numBytes, CFunction.FUNCFLAG_CDECL ); ! //this.memoryBacked = true; ! //this.isAtomic = true; } *************** *** 36,40 **** public void destroy() throws Throwable { synchronized (this) { ! fini(this.address); this.address = 0; this.memoryBacked = false; --- 37,41 ---- public void destroy() throws Throwable { synchronized (this) { ! fini(this.thunk); this.address = 0; this.memoryBacked = false; *************** *** 47,50 **** --- 48,52 ---- } + /** * Allocate a trampoline that calls this object back on the call() method. *************** *** 61,65 **** * @param address A pointer to the trampoline. */ ! protected native void fini(long address ); } --- 63,82 ---- * @param address A pointer to the trampoline. */ ! protected native void fini(long thunk ); ! ! public void setAddress(long i, int syncDirection) throws CException { ! super.setAddress(i, syncDirection); ! if (isMemoryBacked()) { ! ! if (syncDirection == SYNCDIR_TOC) { ! pokeThunk(thunk); ! } else if (syncDirection == SYNCDIR_TOJAVA) { ! thunk = peekThunk(); ! } ! } ! } ! ! protected native void pokeThunk(long i); ! protected native long peekThunk(); } Index: CStruct.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/CStruct.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CStruct.java 22 Mar 2004 05:55:36 -0000 1.4 --- CStruct.java 29 Aug 2004 01:25:28 -0000 1.5 *************** *** 161,165 **** if (Modifier.isPublic(modifiers) && ! Modifier.isStatic(modifiers)) { try { ! fields.add(f[i].get(this)); } catch (IllegalAccessException e) { e.printStackTrace(); --- 161,174 ---- if (Modifier.isPublic(modifiers) && ! Modifier.isStatic(modifiers)) { try { ! Object val = f[i].get(this); ! if (val == null) { ! try { ! val = f[i].getType().newInstance(); ! } catch (InstantiationException e) { ! e.printStackTrace(); ! } ! } ! fields.add(val); ! } catch (IllegalAccessException e) { e.printStackTrace(); Index: CFunction.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/CFunction.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CFunction.java 23 Mar 2004 06:37:33 -0000 1.3 --- CFunction.java 29 Aug 2004 01:25:28 -0000 1.4 *************** *** 45,49 **** this.handle = load(dll.getHandle(), symbol); } ! public static CFunction loadNativeFunction(CDLL dll, String symbol) throws CSymbolNotFoundException { --- 45,54 ---- this.handle = load(dll.getHandle(), symbol); } ! ! public CFunction(String dll, String symbol)throws CSymbolNotFoundException { ! this.symbol = symbol; ! this.dll = CDLL.LoadLibrary(dll); ! this.handle = load(this.dll.getHandle(), symbol); ! } public static CFunction loadNativeFunction(CDLL dll, String symbol) throws CSymbolNotFoundException { *************** *** 80,84 **** if (args != null) { for (int i = 0; i < args.length; i++) { ! if (!(args[i] instanceof CType)) { throw new IllegalArgumentException("No types other than CTypes can be passed to this function."); } --- 85,89 ---- if (args != null) { for (int i = 0; i < args.length; i++) { ! if (!(args[i] instanceof CType) && (args[i] != null)) { throw new IllegalArgumentException("No types other than CTypes can be passed to this function."); } *************** *** 104,107 **** --- 109,113 ---- args = new Object[0]; } + return callInternal(handle, restype, args, flags); } Index: CType.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/CType.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CType.java 30 Mar 2004 21:56:57 -0000 1.5 --- CType.java 29 Aug 2004 01:25:28 -0000 1.6 *************** *** 23,27 **** package ctypes.java; - import java.util.Properties; /** --- 23,26 ---- |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:25:39
|
Update of /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/win32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18970/src/java/ctypes/java/win32 Modified Files: RECT.java PROCESSENTRY32W.java PROCESSENTRY32A.java MODULEENTRY32W.java Log Message: Index: MODULEENTRY32W.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/win32/MODULEENTRY32W.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MODULEENTRY32W.java 10 Mar 2004 01:56:34 -0000 1.2 --- MODULEENTRY32W.java 29 Aug 2004 01:25:29 -0000 1.3 *************** *** 25,29 **** import ctypes.java.CInt; import ctypes.java.CStruct; - import ctypes.java.CType; import ctypes.java.CWString; --- 25,28 ---- Index: RECT.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/win32/RECT.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RECT.java 10 Mar 2004 01:56:34 -0000 1.2 --- RECT.java 29 Aug 2004 01:25:29 -0000 1.3 *************** *** 25,29 **** import ctypes.java.CInt; import ctypes.java.CStruct; - import ctypes.java.CType; /** --- 25,28 ---- Index: PROCESSENTRY32A.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/win32/PROCESSENTRY32A.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PROCESSENTRY32A.java 10 Mar 2004 01:56:34 -0000 1.2 --- PROCESSENTRY32A.java 29 Aug 2004 01:25:29 -0000 1.3 *************** *** 4,8 **** import ctypes.java.CString; import ctypes.java.CStruct; - import ctypes.java.CType; --- 4,7 ---- Index: PROCESSENTRY32W.java =================================================================== RCS file: /cvsroot/ctypes/ctypes-java/src/java/ctypes/java/win32/PROCESSENTRY32W.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PROCESSENTRY32W.java 10 Mar 2004 01:56:34 -0000 1.2 --- PROCESSENTRY32W.java 29 Aug 2004 01:25:29 -0000 1.3 *************** *** 25,29 **** import ctypes.java.CInt; import ctypes.java.CStruct; - import ctypes.java.CType; import ctypes.java.CWString; --- 25,28 ---- |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:25:39
|
Update of /cvsroot/ctypes/ctypes-java/src/examples/ctypes/java/ntlm/httpclient In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18970/src/examples/ctypes/java/ntlm/httpclient Removed Files: test.sh Log Message: --- test.sh DELETED --- |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:23:26
|
Update of /cvsroot/ctypes/ctypes-java/src/java/mds In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18550/src/java/mds Log Message: Directory /cvsroot/ctypes/ctypes-java/src/java/mds added to the repository |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:23:25
|
Update of /cvsroot/ctypes/ctypes-java/src/java/mds/hotknife In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18550/src/java/mds/hotknife Log Message: Directory /cvsroot/ctypes/ctypes-java/src/java/mds/hotknife added to the repository |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:23:23
|
Update of /cvsroot/ctypes/ctypes-java/src/java/mds/hotknife/http In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18550/src/java/mds/hotknife/http Log Message: Directory /cvsroot/ctypes/ctypes-java/src/java/mds/hotknife/http added to the repository |
From: Bradley L S. <bs...@us...> - 2004-08-29 01:23:23
|
Update of /cvsroot/ctypes/ctypes-java/src/jni/libffi_msvc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18550/src/jni/libffi_msvc Log Message: Directory /cvsroot/ctypes/ctypes-java/src/jni/libffi_msvc added to the repository |