Using CDecl for Managed Callbacks

  • Thread starter Thread starter KW
  • Start date Start date
K

KW

I am converting a multithreaded MFC application to Managed C++ under
VS2003 that uses a DLL that was compiled in Microsoft Visual Fortran 6.
The main function of the fortran DLL (FVIS2FOR) takes a pointer to a
function (UpdateVC) that updates a status window periodically. I am
using a delegate to attempt to accomplish the same thing in .NET, but
it doesn't quite work. The DLL will call the function and the function
appears to act correctly, but the DLL generates an access violation
immediately after the callback function terminates. I believe it is
due to a mismatch between the calling conventions of the two functions.

The MFC function declaration follows:
void __cdecl UpdateVC(/* a long list of arguments */);

The above function then calls another function that actually updates
the window.

LoadLibrary and GetProcAddress are used to get a pointer to the
FVIS2FOR function, which is declaraed like this:

typedef void (__stdcall *LPFVIS2FOR)(void*, /* several more
arguments*/);

I am trying to accomplish this in .NET with a delegate:

public __delegate void UpdateVCDelegate(/*same list of arguments);

[System::Runtime::InteropServices::DllImport(S"mydll.dll",
EntryPoint=S"FVIS2FOR", SetLastError=true,
CharSet=System::Runtime::InteropServices::CharSet::Ansi,
ExactSpelling=true,
CallingConvention=System::Runtime::InteropServices::CallingConvention::StdCall)]
extern "C" void FVIS2FOR(UpdateVCDelegate * UpdateVC, /* another long
list of arguments */)

So in a nutshell, I have a fortran DLL that needs to take in a pointer
to a managed function that updates a windows form, and the DLL expects
the function to use the Cdecl calling convention. Does anybody have
any suggestions on how to accomplish this?

Thanks,
KW
 
KW said:
I am converting a multithreaded MFC application to Managed C++ under
VS2003 that uses a DLL that was compiled in Microsoft Visual Fortran
6.
The main function of the fortran DLL (FVIS2FOR) takes a pointer to a
function (UpdateVC) that updates a status window periodically. I am
using a delegate to attempt to accomplish the same thing in .NET, but
it doesn't quite work. The DLL will call the function and the
function
appears to act correctly, but the DLL generates an access violation
immediately after the callback function terminates. I believe it is
due to a mismatch between the calling conventions of the two
functions.

The MFC function declaration follows:
void __cdecl UpdateVC(/* a long list of arguments */);

The above function then calls another function that actually updates
the window.

LoadLibrary and GetProcAddress are used to get a pointer to the
FVIS2FOR function, which is declaraed like this:

typedef void (__stdcall *LPFVIS2FOR)(void*, /* several more
arguments*/);

I am trying to accomplish this in .NET with a delegate:

public __delegate void UpdateVCDelegate(/*same list of arguments);

[System::Runtime::InteropServices::DllImport(S"mydll.dll",
EntryPoint=S"FVIS2FOR", SetLastError=true,
CharSet=System::Runtime::InteropServices::CharSet::Ansi,
ExactSpelling=true,
CallingConvention=System::Runtime::InteropServices::CallingConvention::StdCall)]
extern "C" void FVIS2FOR(UpdateVCDelegate * UpdateVC, /* another long
list of arguments */)

So in a nutshell, I have a fortran DLL that needs to take in a pointer
to a managed function that updates a windows form, and the DLL expects
the function to use the Cdecl calling convention. Does anybody have
any suggestions on how to accomplish this?

Directly, you can't.

You need to supply an unmanaged C++ __cdecl function that's called by the
Fortran code that in turn calls through the .NET delegate.

-cd
 
Back
Top