-
Notifications
You must be signed in to change notification settings - Fork 555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XS INTERFACE: token doesn't support calling conventions #14327
Comments
From @bulk88I tried using INTERFACE: keyword with __stdcall C functions (all MS Also as far as I can tell, I can't rename a XSUB in Perl namespace to be "fixed" .xs chunk below for example const void * reset = ResetEvent;
const void * set = SetEvent;
/* otherwise INTERFACE: crashes below since the default is __cdecl */
#undef XSINTERFACE_CVT
#undef XSINTERFACE_CVT_ANON
#define XSINTERFACE_CVT(ret,name) ret (__stdcall *name)()
#define XSINTERFACE_CVT_ANON(ret) ret (__stdcall *)()
MODULE = Win32::Event PACKAGE = Win32::Event
BOOL
handleInBoolOut(event)
HANDLE event
INTERFACE:
PulseEvent reset set The standard call functions are declared as #line 2967 "C:\\Program Files\\Microsoft Visual Studio .NET
2003\\VC7\\PlatformSDK\\include\\winbase.h"
__declspec(dllimport)
void
__stdcall DeleteCriticalSection(LPCRITICAL_SECTION
lpCriticalSection);
__declspec(dllimport)
BOOL __stdcall
SetEvent(HANDLE hEvent);
__declspec(dllimport)
BOOL __stdcall
ResetEvent(HANDLE hEvent); in MS's headers after CPP. Should I add note to perlxs.pod about INTERFACE's lack of calling Perl Info
|
From @tonycozCan it be done using INTERFACE_MACRO? #define XSINTERFACE_FUNC_STDCALL(ret,cv,f) ((ret (__stdcall *)())(f))
...
BOOL handleInBoolOut(event)
HANDLE event
INTERFACE:
PulseEvent reset set
INTERFACE_MACRO:
XSINTERFACE_FUNC_STDCALL
XSINTERFACE_FUNC_SET Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @bulk88I am not sure if you are proposing a new API or using INTERFACE_MACRO keyword as is. If as is, not according to the docs which say
These seems to be written for C++/faux-C++ vtables, MS COM/OLE perhaps (see http://www.codeproject.com/Articles/14117/COM-in-plain-C-Part#premain4 where QueryInterface would be the offset into the vtable, the actual function pointer can never be stored in the CV * because each may/probably has a different QueryInterface func ptr), where the function pointer of what to call isn't store in CV's ANY member, but an offset into a table of function pointers, so the function pointers in the RW vtable can get swaped out after the CV is registered/newXSed. This does NOT affect how the function pointer is invoked, only how the CV's ANY member is converted to a function pointer. XS_EUPXS(XS_Win32__Event_handleInBoolOut); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Win32__Event_handleInBoolOut)
{
dVAR; dXSARGS;
dXSFUNCTION(BOOL);
if (items != 1)
croak_xs_usage(cv, "event");
{
HANDLE event;
BOOL RETVAL;
{
SV * tsv = ST(0);
if (sv_derived_from(tsv, "Win32::Event")) {
IV tmp = SvIV((SV*)SvRV(tsv));
event = INT2PTR(HANDLE, tmp);
}
else
croak("event is not of type Win32::Event");
}
;
XSFUNCTION = XSINTERFACE_FUNC(BOOL,cv,XSANY.any_dptr);
RETVAL = XSFUNCTION(event);
ST(0) = boolSV(RETVAL);
}
XSRETURN(1);
} After CPP.
Now lets look at macro for declaration of function pointer. "dXSFUNCTION(BOOL);"
#define dXSFUNCTION(ret) XSINTERFACE_CVT(ret,XSFUNCTION)
XSINTERFACE_CVT(BOOL,XSFUNCTION);
#define XSINTERFACE_CVT(ret,name) ret (*name)()
BOOL (*XSFUNCTION)(); I tried your suggestion, it still crashed as c stack pointer corruption. #define MYXSINTERFACE_FUNC(ret,cv,ptr) (ret(__stdcall *)())ptr
.....................
BOOL
handleInBoolOut(event)
HANDLE event
INTERFACE_MACRO:
MYXSINTERFACE_FUNC
XSINTERFACE_FUNC_SET
INTERFACE:
PulseEvent reset set CPP output of above XS static void XS_Win32__Event_handleInBoolOut(PerlInterpreter* my_perl , CV* cv);
static void XS_Win32__Event_handleInBoolOut(PerlInterpreter* my_perl , CV* cv)
{
extern int Perl___notused(void); SV **sp = (my_perl->Istack_sp); I32 ax = (*(my_perl->Imarkstack_ptr)--); SV **mark = (my_perl->Istack_base) + ax++; I32 items = (I32)(sp - mark);
>>>>>>>>>>>>>>>>no __stdcall here<<<<<<<<<<<<<<<<<<<<<
BOOL (*XSFUNCTION)();
if (items != 1)
Perl_croak_xs_usage(cv, "event");
{
HANDLE event;
BOOL RETVAL;
{
SV * tsv = (my_perl->Istack_base)[ax + (0)];
if (Perl_sv_derived_from(my_perl, tsv,"Win32::Event")) {
IV tmp = (((((SV*)((tsv)->sv_u.svu_rv))->sv_flags & (0x00000100|0x00200000)) == 0x00000100) ? ((XPVIV*) ((SV*)((tsv)->sv_u.svu_rv))->sv_any)->xiv_u.xivu_iv : Perl_sv_2iv_flags(my_perl, (SV*)((tsv)->sv_u.svu_rv),2));
event = (HANDLE)(tmp);
}
else
Perl_croak_nocontext("event is not of type Win32::Event");
}
;
XSFUNCTION = ((BOOL (*)())(((XPVCV*)((void *) ((cv)->sv_any)))->xcv_start_u.xcv_xsubany.any_dptr));
RETVAL = XSFUNCTION(event);
(my_perl->Istack_base)[ax + (0)] = ((RETVAL) ? &(my_perl->Isv_yes) : &(my_perl->Isv_no));
}
do { const IV tmpXSoff = (1); (my_perl->Istack_sp) = (my_perl->Istack_base) + ax + (tmpXSoff - 1); return; } while (0);
} The result is a syntax error since the func ptrs are of different type.
If you are talking about new API, are you suggesting adding 3rd line for INTERFACE_MACRO? Currently it only takes in 2 lines, here is the chunk from ParseXS. sub INTERFACE_MACRO_handler {
my $self = shift;
$_ = shift;
my $in = $self->merge_section();
trim_whitespace($in);
if ($in =~ /\s/) { # two
($self->{interface_macro}, $self->{interface_macro_set}) = split ' ', $in;
}
else {
$self->{interface_macro} = $in;
$self->{interface_macro_set} = 'UNKNOWN_CVT'; # catch later
}
$self->{interface} = 1; # local
$self->{interfaces} = 1; # global
} I also noticed like this the special interface macros are ignored with no warning. BOOL
handleInBoolOut(event)
HANDLE event
INTERFACE:
PulseEvent reset set
INTERFACE_MACRO:
MYXSINTERFACE_FUNC
XSINTERFACE_FUNC_SET but like this they take effect BOOL
handleInBoolOut(event)
HANDLE event
INTERFACE_MACRO:
MYXSINTERFACE_FUNC
XSINTERFACE_FUNC_SET
INTERFACE:
PulseEvent reset set I think that this 2nd bug is a very low priority over not supporting calling conventions |
From @tonycozI was suggesting using them as is. I didn't test it. I hadn't looked at the generated code, so I didn't see the assignment. Maybe there could be a third line for INTERFACE_MACRO that lets you supply a macro name for the function type, though that would be messy with the way other macros use the XSINTERFACE_CVT macro. If you supply a reasonable patch for some approach (not necessarily my approach) for this I'll apply it. Tony |
@bulk88 how do you want to proceed with this case? |
Migrated from rt.perl.org#123415 (status was 'open')
Searchable as RT123415$
The text was updated successfully, but these errors were encountered: