Explorar o código

feat: 增加了C函数调用的形参类型

增加了int32, int64等
增加了对null, true等的处理

link #9
SongZihuan %!s(int64=4) %!d(string=hai) anos
pai
achega
8811639b80

+ 1 - 0
VirtulMathCore/include/macro.h

@@ -29,5 +29,6 @@
 #define true 1
 #define false 0
 #define NUL ((char)0)
+#define WNUL ((wchar_t)0)
 
 #endif //VIRTUALMATH_MACRO_H

+ 12 - 0
VirtulMathCore/include/parameter.h

@@ -57,10 +57,22 @@ struct ArgumentFFI {
     ffi_type **arg;  // arg的类型
     void **arg_v;  // arg的真实数值
     enum ArgumentFFIType{
+        af_usint,
+        af_sint,
+        af_uint,
         af_int,
+        af_ulint,
+        af_lint,
+
+        af_float,
         af_double,
+        af_ldouble,
+
         af_str,
+
+        af_uchar,
         af_char,
+
         af_void,
     } *type;  // 数据类型 (决定如何释放arg_v)
     unsigned int size;  // 数组长度

+ 115 - 72
VirtulMathCore/src/parameter.c

@@ -881,6 +881,7 @@ void freeArgumentFFI(ArgumentFFI *af) {
         switch (af->type[i]) {
             case af_double:
             case af_int:
+            case af_char:
                 memFree(af->arg_v[i]);
                 break;
             case af_str:
@@ -921,94 +922,136 @@ bool listToArgumentFFI(ArgumentFFI *af, LinkValue **list, vint size) {
     return true;
 }
 
+#define setFFIValue(v_t, ffi_t, af_t, type_, data_) case v_t: \
+af->arg[i] = &ffi_t;  /* af->arg是ffi_type **arg, 即*arg[] */ \
+af->type[i] = af_t; \
+af->arg_v[i] = (type_ *)memCalloc(1, sizeof(type_));  /* af->arg_v是ffi_type **arg_v, 即 *arg_v[] */ \
+*(type_ *)(af->arg_v[i]) = (type_)(data_); \
+break
+
+static bool setFFIArgFromValue(ArgumentFFI *af, Argument *arg, unsigned int i) {
+    switch (arg->data.value->value->type) {
+        setFFIValue(V_int, ffi_type_sint32, af_int, int, arg->data.value->value->data.int_.num);
+        setFFIValue(V_dou, ffi_type_double, af_double, double, arg->data.value->value->data.dou.num);
+        setFFIValue(V_bool, ffi_type_sint32, af_int, double, arg->data.value->value->data.bool_.bool_);
+        setFFIValue(V_str, ffi_type_pointer, af_str, char *, memWcsToStr(arg->data.value->value->data.str.str, false));
+        setFFIValue(V_none, ffi_type_sint32, af_int, int, 0);
+        default:
+            return false;
+    }
+    return true;
+}
+
+#undef setFFIValue
+#define setFFIArgFromTypeNumber(aft_type, type_) \
+case aft_type: \
+    do { \
+    af->arg_v[i] = memCalloc(1, sizeof(type_)); \
+    switch (arg->data.value->value->type) { \
+        case V_int: \
+            *(type_ *)(af->arg_v[i]) = (type_)arg->data.value->value->data.int_.num; \
+            break; \
+        case V_dou: \
+            *(type_ *)(af->arg_v[i]) = (type_)arg->data.value->value->data.dou.num; \
+            break; \
+        case V_none: \
+            *(type_ *)(af->arg_v[i]) = (type_)0; \
+            break; \
+        case V_bool: \
+            *(type_ *)(af->arg_v[i]) = (type_)arg->data.value->value->data.bool_.bool_; \
+            break; \
+        default: \
+            return false; \
+    } } while(0); \
+break
+
+#define setFFIArgFromTypeChar(aft_type, type_) case aft_type: \
+    af->arg_v[i] = memCalloc(1, sizeof(type_)); \
+    if (arg->data.value->value->type == V_str && memWidelen(arg->data.value->value->data.str.str) == 1) \
+        *(type_ *)(af->arg_v[i]) = (type_)(arg->data.value->value->data.str.str[0]); \
+    else \
+        return false; \
+break
+
+static bool setFFIArgFromType(ArgumentFFI *af, Argument *arg, unsigned int i) {
+    switch (af->type[i]) {
+        setFFIArgFromTypeNumber(af_sint, int16_t);
+        setFFIArgFromTypeNumber(af_usint, u_int16_t);
+        setFFIArgFromTypeNumber(af_int, int32_t);
+        setFFIArgFromTypeNumber(af_uint, u_int32_t);
+        setFFIArgFromTypeNumber(af_lint, int64_t);
+        setFFIArgFromTypeNumber(af_ulint, u_int64_t);
+
+        setFFIArgFromTypeNumber(af_float, float);
+        setFFIArgFromTypeNumber(af_ldouble, long double);
+        setFFIArgFromTypeNumber(af_double, double);
+
+        setFFIArgFromTypeChar(af_char, int8_t);
+        setFFIArgFromTypeChar(af_uchar, u_int8_t);
+
+        case af_str:
+            af->arg_v[i] = memCalloc(1, sizeof(char *));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
+            if (arg->data.value->value->type == V_str) {
+                *(char **)(af->arg_v[i]) = memWcsToStr(arg->data.value->value->data.str.str, false);
+            } else
+                return false;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+
+#undef setFFIArgFromTypeNumber
+#undef setFFIArgFromTypeChar
+
 bool setArgumentToFFI(ArgumentFFI *af, Argument *arg) {
     for (unsigned int i=0; arg != NULL && i < af->size; arg = arg->next, i++) {
-        if (af->arg[i] == NULL) {
-            switch (arg->data.value->value->type) {
-                case V_int:
-                    af->arg[i] = &ffi_type_sint;  // af->arg是ffi_type **arg, 即*arg[]
-                    af->type[i] = af_int;
-
-                    af->arg_v[i] = (int *)memCalloc(1, sizeof(int));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
-                    *(int *)(af->arg_v[i]) = (int)arg->data.value->value->data.int_.num;
-                    break;
-                case V_dou:
-                    af->arg[i] = &ffi_type_double;  // af->arg是ffi_type **arg, 即*arg[]
-                    af->type[i] = af_double;
-
-                    af->arg_v[i] = (double *)memCalloc(1, sizeof(double));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
-                    *(double *)(af->arg_v[i]) = (double)arg->data.value->value->data.dou.num;
-                    break;
-                case V_str:
-                    af->arg[i] = &ffi_type_pointer;  // af->arg是ffi_type **arg, 即*arg[]
-                    af->type[i] = af_str;
-
-                    af->arg_v[i] = (char **)memCalloc(1, sizeof(char **));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
-                    *(char **)(af->arg_v[i]) = (char *)memWcsToStr(arg->data.value->value->data.str.str, false);
-                    break;
-                default:
-                    return false;
-            }
-        } else {
-            switch (af->type[i]) {
-                case af_int:
-                    af->arg_v[i] = (int *)memCalloc(1, sizeof(int));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
-                    switch (arg->data.value->value->type) {
-                       case V_int:
-                           *(int *)(af->arg_v[i]) = (int)arg->data.value->value->data.int_.num;
-                           break;
-                       case V_dou:
-                           *(int *)(af->arg_v[i]) = (int)arg->data.value->value->data.dou.num;
-                           break;
-                       default:
-                           return false;
-                   }
-                   break;
-                case af_double:
-                    af->arg_v[i] = (double *)memCalloc(1, sizeof(double));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
-                    switch (arg->data.value->value->type) {
-                        case V_int:
-                            *(double *)(af->arg_v[i]) = (double)arg->data.value->value->data.int_.num;
-                            break;
-                        case V_dou:
-                            *(double *)(af->arg_v[i]) = (double)arg->data.value->value->data.dou.num;
-                            break;
-                        default:
-                            return false;
-                    }
-                    break;
-                case af_str:
-                    af->arg_v[i] = (double *)memCalloc(1, sizeof(char *));  // af->arg_v是ffi_type **arg_v, 即 *arg_v[]
-                    if (arg->data.value->value->type == V_str) {
-                        *(char **)(af->arg_v[i]) = memWcsToStr(arg->data.value->value->data.str.str, false);
-                    } else
-                        return false;
-                    break;
-                default:
-                    return false;
-            }
-        }
+        if (af->arg[i] == NULL && !setFFIArgFromValue(af, arg, i) ||
+            af->arg[i] != NULL && !setFFIArgFromType(af, arg, i))
+            return false;
     }
-    return arg == NULL ? true : false;
+    return arg == NULL;  // 若arg还没迭代完, 则证明有问题
 }
 
-ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft) {
+ffi_type *getFFIType(wchar_t *str, enum ArgumentFFIType *aft) {\
     ffi_type *return_ = NULL;
     if (eqWide(str, L"int")) {
-        return_ = &ffi_type_sint;
+        return_ = &ffi_type_sint32;
         *aft = af_int;
-    } else if (eqWide(str, L"dou")) {
+    } else if (eqWide(str, L"uint")) {
+        return_ = &ffi_type_uint32;
+        *aft = af_uint;
+    } else if (eqWide(str, L"sint")) {
+        return_ = &ffi_type_sint16;
+        *aft = af_sint;
+    } else if (eqWide(str, L"usint")) {
+        return_ = &ffi_type_uint16;
+        *aft = af_usint;
+    } else if (eqWide(str, L"lint")) {
+        return_ = &ffi_type_sint64;
+        *aft = af_lint;
+    } else if (eqWide(str, L"ulint")) {
+        return_ = &ffi_type_uint64;
+        *aft = af_ulint;
+    } else if (eqWide(str, L"float")) {
+        return_ = &ffi_type_float;
+        *aft = af_float;
+    } else if (eqWide(str, L"double")) {
         return_ = &ffi_type_double;
         *aft = af_double;
+    } else if (eqWide(str, L"ldouble")) {
+        return_ = &ffi_type_longdouble;
+        *aft = af_ldouble;
     } else if (eqWide(str, L"str")) {
         return_ = &ffi_type_pointer;
         *aft = af_str;
-    } else if (eqWide(str, L"void")) {
-        return_ = &ffi_type_void;
-        *aft = af_void;
     } else if (eqWide(str, L"char")) {
         return_ = &ffi_type_schar;
         *aft = af_char;
+    } else if (eqWide(str, L"void")) {
+        return_ = &ffi_type_void;
+        *aft = af_void;
     }
     return return_;
 }

+ 16 - 3
VirtulMathCore/src/runcall.c

@@ -281,23 +281,35 @@ static bool makeFFIReturn(enum ArgumentFFIType af, void **re_v) {
 
 static bool FFIReturnValue(enum ArgumentFFIType aft, void *re_v, fline line, char *file, FUNC_NT) {
     switch (aft) {  // 应用返回值函数
+        case af_usint:
+        case af_sint:
+        case af_uint:
         case af_int:
+        case af_ulint:
+        case af_lint:
             makeIntValue((vint)*(int64_t *)re_v, line, file, CNEXT_NT);  // 先以(int64_t)读取void *类型的数据, 再转换成(vint)类型 (避免大端和小端模式的行为不同)
             break;
+
+        case af_float:
+        case af_ldouble:
         case af_double:
             makeDouValue((vdou)*(long double *)re_v, line, file, CNEXT_NT);
             break;
+
         case af_str: {
             wchar_t *tmp = memStrToWcs(re_v, false);
             makeStringValue(tmp, line, file, CNEXT_NT);
             memFree(tmp);
             break;
         }
+
+        case af_uchar:
         case af_char: {
-            wchar_t tmp[] = {(wchar_t)(*(char *)re_v), (wchar_t)NUL};
+            wchar_t tmp[] = {(wchar_t)(*(int64_t *)re_v), WNUL};
             makeStringValue(tmp, line, file, CNEXT_NT);
             break;
         }
+
         case af_void:
             setResult(result, inter);
             break;
@@ -314,6 +326,7 @@ static ffi_type *getRearg(LinkValue *function_value, enum ArgumentFFIType *aft,
     if (!CHECK_RESULT(result))
         return NULL;
     freeResult(result);
+
     if (re_var != NULL) {
         if (re_var->value->type != V_str) {
             setResultError(E_TypeException, ONLY_ACC(rearg, str), line, file, true, CNEXT_NT);
@@ -325,7 +338,7 @@ static ffi_type *getRearg(LinkValue *function_value, enum ArgumentFFIType *aft,
             return NULL;
         }
     } else
-        re = &ffi_type_void;
+        re = &ffi_type_sint32;
     return re;
 }
 
@@ -356,7 +369,7 @@ static ResultType callFFunction(LinkValue *function_value, Argument *arg, long i
     ffi_type *re;
     unsigned int size;
     ArgumentFFI af;
-    enum ArgumentFFIType aft = af_void;
+    enum ArgumentFFIType aft = af_int;
     void *re_v = NULL;  // 存放返回值的函數
 
     setResultCore(result);