Calling DLL subroutine from C++

  • Follow


I am able to invoke a subroutine in my DLL successfully, and all seems OK until 
the execution is complete.  On return from the DLL subroutine my C++/Qt 
application crashes silently.

My subroutine expects an integer and four character arrays:

subroutine execute(ncpu,infile,outfile,resfile,runfile)
!DEC$ ATTRIBUTES DLLEXPORT :: EXECUTE
!DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE" :: execute
integer :: ncpu
character*(*) :: infile,outfile,resfile,runfile

I am calling the DLL from within a thread, but I don't think that is 
significant.  Here is the C++:

void ExecThread::run()
{
....
   QLibrary myLib(dll_path);

   typedef int (*MyPrototype)(int *, char *, int, char *, int, char *, int, char 
*, int);
   MyPrototype execute = (MyPrototype) myLib.resolve("EXECUTE");
   if (execute) {	
      execute(...)
   }
   myLib.unload();
}

If I comment out the call to execute() the program doesn't crash.  I suspect the 
problem is stack related.  This same invocation works fine in Python (using 
windll.LoadLibrary()), and apparently almost works here, since the subroutine 
executes correctly.  I know it's a long shot asking for help on this, since I'm 
using not only C++ but also Qt.
0
Reply Gib 3/29/2010 6:59:10 AM

Gib Bogle wrote:

> !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE" 

Replacing STDCALL by C makes this work.  C++ apparently has a different calling 
convention than Python, which needs STDCALL.
0
Reply Gib 3/29/2010 8:33:52 AM


On 29 mrt, 10:33, Gib Bogle <g.bo...@auckland.no.spam.ac.nz> wrote:
> Gib Bogle wrote:
> > !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE"
>
> Replacing STDCALL by C makes this work. =A0C++ apparently has a different=
 calling
> convention than Python, which needs STDCALL.

This really depends on the compiler used.

STDCALL ordinarily does more than just change the calling
convention - it also adds a suffix "@nn" to the link name of
the routines (where nn is the number of bytes in the interface).
Via aliases that may become invisible.

Regards,

Arjen
0
Reply Arjen 3/29/2010 8:47:46 AM

Gib Bogle wrote:
> Gib Bogle wrote:
> 
>> !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE" 
> 
> Replacing STDCALL by C makes this work.  C++ apparently has a different 
> calling convention than Python, which needs STDCALL.

I suppose you've just found the reason why that calling convention is
called "C" :-).

--
Jugoslav
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
0
Reply Jugoslav 3/29/2010 9:22:05 AM

Gib Bogle wrote:
> Gib Bogle wrote:
> 
>> !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE" 
> 
> Replacing STDCALL by C makes this work.  C++ apparently has a different 
> calling convention than Python, which needs STDCALL.

Alternatively, slap a "__stdcall" on your function pointer type---the 
default, as you discovered, is __cdecl.  It may also need to be 'extern 
"C"'; I don't recall offhand whether that has any impact beyond name 
mangling to where it would be needed here.
0
Reply Craig 3/29/2010 4:02:03 PM

Arjen Markus wrote:
> On 29 mrt, 10:33, Gib Bogle <g.bo...@auckland.no.spam.ac.nz> wrote:
>> Gib Bogle wrote:
>>> !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE"
>> Replacing STDCALL by C makes this work.  C++ apparently has a different calling
>> convention than Python, which needs STDCALL.
> 
> This really depends on the compiler used.
> 
> STDCALL ordinarily does more than just change the calling
> convention - it also adds a suffix "@nn" to the link name of
> the routines (where nn is the number of bytes in the interface).
> Via aliases that may become invisible.

That's not really an issue here, though.  The ALIAS attribute on the 
Fortran side avoids the stdcall name mangling.  The part that really 
matters is the difference in calling convention.
0
Reply Craig 3/29/2010 4:02:57 PM

Jugoslav Dujic wrote:
> Gib Bogle wrote:
>> Gib Bogle wrote:
>>
>>> !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE" 
>>
>> Replacing STDCALL by C makes this work.  C++ apparently has a 
>> different calling convention than Python, which needs STDCALL.
> 
> I suppose you've just found the reason why that calling convention is
> called "C" :-).

:-)  What misled me to expect the behaviour with Python to be the same as that 
with C++/Qt is that I'm using PyQt - but of course the windll.LoadLibrary 
facility is straight Python, with no Qt involvement.  It's all so confusing ... 
  But I'm very proud of myself for having almost completely translated my 
Python/PyQt GUI code into C++/Qt - a crash course in C++.  C++ is both wonderful 
and horrible.  The power of the object approach is obvious, but the complexity 
is daunting.  I must say I've come to have great respect for the standardized 
documentation of the classes that Qt provides, but life in the Fortran world is 
so much simpler.

There is absolutely no doubt in my mind that C++ is the obvious language to use 
for the kind of stuff that Qt does.  I wouldn't want to develop my model with 
it, though.
0
Reply Gib 3/29/2010 10:23:59 PM

Craig Powers wrote:
> Gib Bogle wrote:
>> Gib Bogle wrote:
>>
>>> !DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"EXECUTE" 
>>
>> Replacing STDCALL by C makes this work.  C++ apparently has a 
>> different calling convention than Python, which needs STDCALL.
> 
> Alternatively, slap a "__stdcall" on your function pointer type---the 
> default, as you discovered, is __cdecl.  It may also need to be 'extern 
> "C"'; I don't recall offhand whether that has any impact beyond name 
> mangling to where it would be needed here.

Thanks, I'll try that.
0
Reply Gib 3/29/2010 10:24:41 PM

7 Replies
539 Views

(page loaded in 0.115 seconds)

Similiar Articles:













7/23/2012 9:44:55 PM


Reply: