1/* Example code for a C-library accessible from ML 2using the CInterface structure. 3 4Copyright David C.J. Matthews 1999, 2009, 2015 5 6This library is free software; you can redistribute it and/or 7modify it under the terms of the GNU Lesser General Public 8License version 2.1 as published by the Free Software Foundation. 9 10This library is distributed in the hope that it will be useful, 11but WITHOUT ANY WARRANTY; without even the implied warranty of 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13Lesser General Public License for more details. 14 15You should have received a copy of the GNU Lesser General Public 16License along with this library; if not, write to the Free Software 17Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18*/ 19/* 20Linux: cc -shared -o Foreign ForeignTest.c 21Windows: cl /MT ForeignTest.c /link /dll /out:Foreign.dll /def:Foreign.def 22Mac OS X : cc -dynamiclib -o Foreign.dylib ForeignTest.c 23*/ 24#include <stdlib.h> 25#include <string.h> 26#include <stdio.h> 27 28/* Return a string duplicated n Times. */ 29char *DupNString(int n, char *str) 30{ 31 int nSize = strlen(str); 32 char *res = malloc(n*nSize + 1); 33 int i; 34 *res = 0; 35 for (i = 0; i < n; i++) strcat(res, str); 36 return res; 37} 38typedef struct _tree { 39 struct _tree *left, *right; 40 int nValue; 41} *tree; 42 43int SumTree(tree t) 44{ 45 if (t == NULL) return 0; 46 else return t->nValue + SumTree(t->left) + SumTree(t->right); 47} 48 49/* Tests to see whether small structures are returned specially. */ 50struct r2 { int n, m; }; 51 52struct r2 ReturnR2(int n, int m) 53{ 54 struct r2 ret; 55 ret.n = n + 1; 56 ret.m = m + 1; 57 return ret; 58} 59 60/* Added. Callback function. */ 61 62typedef int(*INT_INT_CALLBACK) (int a, int b); 63 64int MakeCallback(int i, INT_INT_CALLBACK p) 65{ 66 return (*p)(i, 4) + (*p)(i + 1, 5); 67} 68 69 70/* Another callback function. This tests the various argument types. */ 71typedef double(*DBL_CALLBACK) (int a, char b, double c, float d, short e, int *f); 72 73double MakeCallback2(DBL_CALLBACK p) 74{ 75 int x = 1; 76 double y = p(12345, 'X', (double)1.414, (float)2.8, 44, &x); 77 return y; 78} 79 80// Check that void results work for callbacks. 81void MakeCallback3(void(*mlcall)(int), int i) 82{ 83 mlcall(i + 1); 84} 85 86/* Test for finalisation. */ 87void *AllocateIt() 88{ 89 void *p = malloc(1); 90 printf("Allocated object at %p\n", p); 91 fflush(stdout); 92 return p; 93} 94 95void FreeIt(void *p) 96{ 97 printf("Freed object at %p\n", p); 98 fflush(stdout); 99 free(p); 100} 101 102/* Test for call-by-reference. Added in updated FFI. */ 103void UpdateArg(int i, int *p) 104{ 105 *p += i; 106} 107 108/* Test for returning a function. Added in updated FFI. */ 109static int acallBack(int q) 110{ 111 return q * 2; 112} 113 114typedef int(*CB)(int); 115 116void ReturnFn(CB *v) 117{ 118 *v = acallBack; 119} 120