Re: gec: Is it possible to specify a signature for a external C call?
Berend de Boer <[email protected]> Wed, 14 Nov 2007 09:59:31 +1300
| Newsgroups | gmane.comp.lang.eiffel.gobo.general |
|---|---|
| Message-ID | <[email protected]> |
>>>>> "Eric" == Eric Bezault <ericb-D6Qt/9opevxWk0Htik3J/[email protected]> writes: >> It works, because they emit a prototype. That had to be coded, so >> it's not luck. Eric> The luck is that it's not specified anywhere in the standard Eric> and you might have no prototype if you specify a header file Eric> that does not contain such prototype. Well, but that's a bug of the coder isn't it? You specify a header file, but one without the prototype, there's little you can do. Would fail in your case as well, i.e. I write a .h file, but make a type when specifying the header and that bad header exists on my system and there's no warning either. Eric> Does it work as well when you add assertions to these external Eric> routines? Forgot to test that, sorry. But it seems to be the case, For SmartEiffel, more specifically: 1. The Eiffel code: class POSIX_TIME posix_difftime (time_end, time_start: INTEGER): DOUBLE is -- Computes the difference between two times in seconds. require time_end_positive: time_end > 0 external "C" end 2. In the .h file SE generates, I have this: /* Extra external prototype for line 36 of /home/berend/src/eposix/src/capi/spec/se/capi_time.e:*/ T5 posix_difftime(T2 a1,T2 a2); /*POSIX_TIME*/ T5 r414posix_difftime(se_dump_stack*caller,T2 a1,T2 a2); So it generates two things: the extra prototype, and the prototype for the external stub. 3. SE generates a wrapper to call posix_difftime which looks like this: /*POSIX_TIME*/ T5 r414posix_difftime(se_dump_stack*caller,T2 a1,T2 a2){ T5 R=0; void**locals[3]; static se_frame_descriptor fd={"posix_difftime CAPI_TIME",0,3,"time_end%E2%time_start%E2%Result%E5%",1}; se_dump_stack ds; ds.fd=&fd; ds.current=NULL; ds.p=0x19401D04/*l29c2/capi_time.e*/; ds.caller=caller; ds.locals=locals; ds.exception_origin=NULL; locals[0]=(void**)&a1; locals[1]=(void**)&a2; locals[2]=(void**)&R; set_dump_stack_top(&ds);/*link*/ se_require_uppermost_flag=1; if(fd.assertion_flag){ fd.assertion_flag=0; (ds.p=0x19402040/*l32c32/capi_time.e*/); ac_req((int32_t)((a1)>(/*IC*/(T2)(INT8_C(0)))),"time_end_positive"); fd.assertion_flag=1; } /*l36c12/capi_time.e*/(ds.p=0x19402418/*l36c12/capi_time.e*/); R=(posix_difftime(a1,a2)); /*l36c12/capi_time.e*/set_dump_stack_top(caller);/*unlink*/ return R; } And you can see the assertion check there. The stub for the external call is always generated in debug mode. Haven't looked at boost mode. You wouldn't need it in that case I imagine. You only need a stub if you want to see a stack frame perhaps, and if you want to check assertions. For ISE Eiffel the situation is similar: 1. A prototype is generated: extern EIF_REAL_64 posix_difftime(EIF_INTEGER_32, EIF_INTEGER_32); 2. A wrapper function is generated: /* posix_difftime */ EIF_TYPED_VALUE Fap3q5s (EIF_REFERENCE Current, EIF_TYPED_VALUE arg1x, EIF_TYPED_VALUE arg2x) { GTCX RTEX; EIF_REAL_64 Result = (EIF_REAL_64) 0; RTSN; RTDA; RTLD; if (arg2x.type == SK_REF) arg2x.it_i4 = * (EIF_INTEGER_32 *) arg2x.it_r; #define arg2 arg2x.it_i4 if (arg1x.type == SK_REF) arg1x.it_i4 = * (EIF_INTEGER_32 *) arg1x.it_r; #define arg1 arg1x.it_i4 RTLI(1); RTLR(0,Current); RTLU (SK_REAL64, &Result); RTLU(SK_INT32,&arg1); RTLU(SK_INT32,&arg2); RTLU (SK_REF, &Current); RTEAA("posix_difftime", RTUD(70), Current, 0, 2, 1114); RTSA(Dtype(Current)); RTSC; RTIV2(Current, RTAL); if (RTAL & CK_REQUIRE | RTAC) { RTHOOK(1); RTCT("time_end_positive", EX_PRE); RTTE((EIF_BOOLEAN)(arg1 > ((EIF_INTEGER_32) 0L)), label_1); RTCK; RTJB; label_1: RTCF; } body:; Result = (EIF_REAL_64)posix_difftime(arg1, arg2); RTVI2(Current, RTAL); RTRS; RTHOOK(2); RTLE; RTLO(4); RTEE; { EIF_TYPED_VALUE r; r.type = SK_REAL64; r.it_r8 = Result; return r; } #undef arg2 #undef arg1 } As you can see, assertion checking works fine. There was an annoying issue with previous versions of EiffelStudio where you could not redefine a feature that was declared external, but that's no longer the case. I hope Gobo allows one redefine external features as well. -- Cheers, Berend de Boer [Non-text portions of this message have been removed]