Using CDecl for Managed Callbacks

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
 
C

Carl Daniel [VC++ MVP]

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top